单击按钮在QFrame中绘制。

时间:2010-07-22 14:06:20

标签: c++ qt drawing qpainter

假设有一个名为“Draw”的QPushButton,一个QLineEdit和一个QFrame。单击按钮我想从QLineEdit中取一个数字并在QFrame中绘制一个圆圈。我怎样才能做到这一点?请提供代码。

P.S。问题是应该在drawEvent方法中调用QPainter的draw方法。

3 个答案:

答案 0 :(得分: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 );
    }
}

答案 1 :(得分: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插槽,一切都应该正常工作。

答案 2 :(得分:1)

你不能画在框架上 从这里开始graphicsview,一开始看起来很复杂 - 但是当你第一次遇到它时,GUI程序是一个很大的飞跃

在大多数GUI(Qt,OpenGL等)中,您构建了一个要在程序中绘制的元素列表并以某种方式存储它们 - 然后有一个draw()函数在计算机需要绘制图片时被调用 - 例如,当它被移动或另一个窗口移动到它前面时。然后调用OnDraw或OnRepaint等函数,你必须绘制对象列表。

另一种方法是将它们全部绘制到图像(QOimage或QPixmap)并将其复制到OnDraw或OnRepaint的屏幕上 - 例如,您可以为图形包执行此操作。