2010-07-22 2 views
3

Скажите, что есть QPushButton с именем «Draw», QLineEdit и QFrame. При нажатии кнопки я хочу взять номер из QLineEdit и нарисовать круг в QFrame. Как я могу это сделать? Пожалуйста, предоставьте мне код.нарисовать QFrame при нажатии кнопки.

P.S. Проблема в том, что методы draw для QPainter следует вызывать в методе drawEvent.

ответ

11

Если для вас недостаточно @Kaleb Pederson's answer, то здесь вы найдете полное решение для простой настройки, соответствующей тому, что вы описали. Протестировано с Qt 4.5.2 на Linux. У меня было немного свободного времени ...;)

main.cpp:

#include <QApplication> 
#include "window.h" 

int main(int argc, char** argv) 
{ 
    QApplication qapp(argc, argv); 

    Window w; 
    w.show(); 

    return qapp.exec(); 
} 

window.h

#pragma once 

class QLineEdit; 
class QPushButton; 
#include <QWidget> 

class Frame; 

class Window : public QWidget 
{ 
Q_OBJECT 

public: 
    Window(); 

private slots: 
    void onButtonClicked(); 

private: 
    QLineEdit* m_lineEdit; 
    QPushButton* m_pushButton; 
    Frame*  m_frame; 
}; 

window.cpp:

#include <QHBoxLayout> 
#include <QLineEdit> 
#include <QPushButton> 
#include <QVBoxLayout> 

#include "frame.h" 
#include "window.h" 

Window::Window() 
    : m_lineEdit (new QLineEdit(this)) 
    , m_pushButton(new QPushButton(tr("Draw"), this)) 
    , m_frame  (new Frame(this)) 
{ 
    connect(m_pushButton, SIGNAL(clicked()) 
      , SLOT(onButtonClicked())); 

    QHBoxLayout*const hLayout = new QHBoxLayout; 
    hLayout->addWidget(m_lineEdit); 
    hLayout->addWidget(m_pushButton); 

    QVBoxLayout*const vLayout = new QVBoxLayout(this); 
    vLayout->addLayout(hLayout); 
    m_frame->setFixedSize(300, 400); 
    vLayout->addWidget(m_frame); 

    setLayout(vLayout); 
} 

void Window::onButtonClicked() 
{ 
    const int r = m_lineEdit->text().toInt(); // r == 0 if invalid 
    m_frame->setCircleRadius(r); 
    m_frame->update(); 
} 

frame.h:

#pragma once 

#include <QFrame> 

class Frame : public QFrame 
{ 
Q_OBJECT 

public: 
    Frame(QWidget*); 

    void setCircleRadius(int); 

protected: 
    void paintEvent(QPaintEvent*); 

private: 
    int m_radius; 
}; 

frame.cpp:

#include <QPainter> 

#include "frame.h" 

Frame::Frame(QWidget* parent) 
    : QFrame(parent) 
    , m_radius(0) 
{ 
    setFrameStyle(QFrame::Box); 
} 

void Frame::setCircleRadius(int radius) 
{ 
    m_radius = radius; 
} 

void Frame::paintEvent(QPaintEvent* pe) 
{ 
    QFrame::paintEvent(pe); 

    if (m_radius > 0) 
    { 
     QPainter p(this); 
     p.drawEllipse(rect().center(), m_radius, m_radius); 
    } 
} 
+0

Это то, что вы сделали все это. Огромное спасибо!!! – Narek

1

Вы не рисуете прямо на раме.
Начало здесь graphicsview, это кажется сложным на первый - но GUI программа представляет собой большой скачок, когда вы впервые столкнулись его

В большинстве ГПИ (Qt, OpenGL и т.д.) вы строите список элементов, которые вы хотите сделать в вашем и сохраните их как-то - тогда есть функция draw(), которая вызывается, когда компьютеру нужно нарисовать ваше изображение - например, когда оно перемещено или другое окно перемещается перед ним. Затем вызывается функция OnDraw или OnRepaint и т. Д., И вам нужно нарисовать список объектов.

Другой способ сделать это - нарисовать их все для изображения (QOimage или QPixmap) и скопировать его на экран в OnDraw или OnRepaint - вы можете сделать это для графического пакета, например.

+3

"Вы не рисовать непосредственно на раме." Почему нет? – Troubadour

+0

«Класс QFrame является базовым классом виджетов, который может иметь фрейм» –

+0

Вы можете рисовать непосредственно на 'QFrame' или любой его подкласс. См. [My anwser] (http://stackoverflow.com/questions/3309708/qt-draw-in-a-qframe-on-clicking-a-button/3310728#3310728) для рабочего примера. – Troubadour

3

Если вы хотите, чтобы ваш кадр, чтобы сделать рисунок, то он нужен способ, чтобы знать, что он должен сделать что-то, таким образом, создать слот, который будет получать уведомления:

/* slot */ void drawCircle(QPoint origin, int radius) { 
    addCircle(origin, radius); 
    update(); // update the UI 
} 

void addCircle(QPoint origin, int radius) { 
    circleList.add(new Circle(origin,radius)); 
} 

Затем ваш кадр подкласс вам нужно переопределить paintEvent(), чтобы нарисовать круг:

void paintEvent(QPaintEvent *event) { 
    QFrame::paintEvent(event); 
    QPainter painter(this); 
    foreach (Circle c, circleList) { // understand foreach requirements 
     painter.drawEllipse(c.origin(), c.radius(), c.radius()); 
    } 
} 

пока слот в ответ на clicked() сигнал кнопки излучает сигнал, который вызывает drawCircle слота с правильными аргументами все должно работать правильно ,