Search code examples
c++qtdrawingqpainter

draw in a QFrame on clicking a button.


Say there is a QPushButton named "Draw", a QLineEdit and a QFrame. On clicking the button I want to take a number from QLineEdit and draw a circle in a QFrame. How can I do this? Please provide me with the code.

P.S. The problem is that draw methods of the QPainter should be called in drawEvent method.


Solution

  • If @Kaleb Pederson's answer is not enough for you then here's a complete solution for a simple set-up matching what you describe. Tested with Qt 4.5.2 on Linux. I had some spare time... ;)

    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 );
        }
    }