Cannot draw with QPainter into a premade QWidget QtCreator



  • Hello all,

    Im trying to draw with QPainter into a widget made from a QtCreator form, that is part of my project.

    In order to make it possible, I ve created a new QWidget child class; its constructor is implemented as follow:

    @
    MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
    {
    ui->setupUi(this);

    }
    @

    It's defined in its .h file as follow:
    @
    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H

    #include <QMainWindow>

    namespace Ui {
    class MainWindow;
    }

    class MainWindow : public QMainWindow
    {
    Q_OBJECT

    public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

    private:
    //Variable set
    Ui::MainWindow *ui;
    QPainter *painter;

    //Function set
    void paintEvent(QPaintEvent *);
    

    };

    #endif // MAINWINDOW_H
    @

    In its paintEvent I've tried to access to the widget created from QtCreator tool, that It's placed 200 px to the left margin, in main window Frame. It doesn't work.

    @
    void MainWindow::paintEvent(QPaintEvent *){
    painter = new QPainter(this->WIDGET_THAT_I_WANT_TO_DRAW_INSIDE);
    painter->begin(this);
    QColor color(200,50,50);
    painter->setRenderHint(QPainter::Antialiasing,true);
    painter->setPen(color);
    painter->setBrush(QBrush(color));
    //
    //painter->drawEllipse(0.0, 0.0, 200.0, 200.0);
    QRectF rectangle(0.0, 100.0, 100.0, 200.0);
    painter->drawRoundedRect(rectangle, 20.0, 15.0);
    painter->end();
    }
    @

    Runtime error is:

    @
    QWidget::paintEngine: Should no longer be called
    QPainter::begin: Paint device returned engine == 0, type: 1
    @

    Even if execution is not aborted. The image that I'm trying to draw seems being located at the main Frame, not inside the widget that I want to draw in (the rounded rect is draw from the window coordinantes, not from the widgets ones).

    I've also tried with some other options, by changing begin parameter from this to this->WIDGET_THAT_I_WANT_TO_DRAW_INSIDE, with no items drawn and the result indicated bellow:

    @
    QWidget::paintEngine: Should no longer be called
    QPainter::begin: Paint device returned engine == 0, type: 1
    QWidget::paintEngine: Should no longer be called
    QPainter::begin: Paint device returned engine == 0, type: 1
    QPainter::setRenderHint: Painter must be active to set rendering hints
    QPainter::setPen: Painter not active
    QPainter::setBrush: Painter not active
    QPainter::end: Painter not active, aborted
    QWidget::paintEngine: Should no longer be called
    QPainter::begin: Paint device returned engine == 0, type: 1
    QWidget::paintEngine: Should no longer be called
    QPainter::begin: Paint device returned engine == 0, type: 1
    @

    I've also tried by accessing directly to the generated _UI class, in paintEvent method:
    @
    painter = new QPainter(this->ui->centralWidget);
    painter->begin(this->ui->centralWidget);
    @

    with the same runtime errors . Generated class UI is:

    @
    #ifndef UI_MAINWINDOW_H
    #define UI_MAINWINDOW_H

    #include <QtCore/QVariant>
    #include <QtWidgets/QAction>
    #include <QtWidgets/QApplication>
    #include <QtWidgets/QButtonGroup>
    #include <QtWidgets/QHeaderView>
    #include <QtWidgets/QListWidget>
    #include <QtWidgets/QMainWindow>
    #include <QtWidgets/QMenuBar>
    #include <QtWidgets/QStatusBar>
    #include <QtWidgets/QToolBar>
    #include <QtWidgets/QWidget>

    QT_BEGIN_NAMESPACE

    class Ui_MainWindow
    {
    public:
    QWidget *centralWidget;
    QWidget *mainContainer;
    QListWidget *listWidget;
    QMenuBar *menuBar;
    QToolBar *mainToolBar;
    QStatusBar *statusBar;

    void setupUi(QMainWindow *MainWindow)
    {
        if (MainWindow->objectName().isEmpty())
            MainWindow->setObjectName(QStringLiteral("MainWindow"));
    

    (.... just init the window components ...)
    retranslateUi(MainWindow);

        QMetaObject::connectSlotsByName(MainWindow);
    } // setupUi
    
    void retranslateUi(QMainWindow *MainWindow)
    {
        MainWindow->setWindowTitle(QApplication::translate("MainWindow", "MainWindow", 0));
    } // retranslateUi
    

    };

    namespace Ui {
    class MainWindow: public Ui_MainWindow {};
    } // namespace Ui

    QT_END_NAMESPACE

    #endif // UI_MAINWINDOW_H
    @

    How can I draw inside the public access QWidget created from QtCreator?

    Thank you for you time



  • Hi, in short words, you can't do this.

    If you want to draw something on a widget, it must be done in the member function paintEvent() of the widget.


    However, you can
    subclass a QWidget,
    re-impl the paintEvent(),
    do what you want for this widget,
    add the widget to you designed ui through "Promote method"



  • Hello,

    Thank you for your fast reply. With this solution, i can add my widget without modifie the ui class created with QtCreator, isnt?

    Well, when I use "promote to" action in QtCreator, I select my MainWindow Widget subclass for the widget component. In compile time, I get this issue:

    @
    ./ui_mainwindow.h: In member function 'void Ui_MainWindow::setupUi(QMainWindow*)':
    ./ui_mainwindow.h:52:22: error: expected type-specifier before 'MainWindow'
    ./ui_mainwindow.h:52:22: error: cannot convert 'int*' to 'MainWindow*' in assignment
    ./ui_mainwindow.h:52:22: error: expected ';' before 'MainWindow'
    @

    I see QtCreator has changed Widget* component for MainWindow* component in its desing:

    @
    //Declaration
    MainWindow *widget;

    //(...) setupId method

         widget = new MainWindow(centralWidget);
        widget->setObjectName(QStringLiteral("widget"));
        widget->setGeometry(QRect(150, 10, 791, 491));
    

    @

    I cannot understad this error, because MainWindow is a Widget's subclass; how it comes this error?

    Thank you.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.