2010-07-22 77 views
3

假設有一個名爲「Draw」的QPushButton,一個QLineEdit和一個QFrame。點擊按鈕,我想從QLineEdit中獲取一個數字,然後在QFrame中繪製一個圓。我怎樣才能做到這一點?請提供我的代碼。單擊按鈕時在QFrame中繪製。

P.S.問題是應該在drawEvent方法中調用QPainter的繪製方法。

回答

11

如果@Kaleb Pederson's answer對您而言還不夠,那麼這裏有一個完整的解決方案,用於一個簡單的設置,與您所描述的相匹配。在Linux上使用Qt 4.5.2進行測試。我有一些空閒時間...;)

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 2010-07-22 16:21:56

1

你不能正確地畫到一個框架上。
從這裏開始graphicsview,看起來比較複雜,在第一次 - 但GUI程序是一個大的飛躍,當你第一次遇到它

在大多數的GUI(QT,OpenGL的等),你建立你想在畫元素的列表中選擇編程並以某種方式存儲它們 - 然後當計算機需要繪製圖片時會調用draw()函數 - 例如,當它被移動或其他窗口移動到其前面時。然後OnDraw或OnRepaint等函數被調用,你必須繪製對象列表。

另一種方法是將它們全部繪製成圖像(QOimage或QPixmap)並將其複製到OnDraw或OnRepaint中的屏幕上 - 例如,您可以對圖形包執行此操作。

+3

「你不直接畫到框架上。」爲什麼不? – Troubadour 2010-07-22 14:31:43

+0

「QFrame類是可以有框架的小部件的基類」 – 2010-07-22 15:40:29

+0

您仍然可以直接在「QFrame」或其任何子類上繪製。請參閱[my anwser](http://stackoverflow.com/questions/3309708/qt-draw-in-a-qframe-on-clicking-a-button/3310728#3310728)瞭解一個工作示例。 – Troubadour 2010-07-22 15:50:26

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插槽以正確的參數一切都應該正常工作的信號。