Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Unable to paint on Qt Widget, shows error “paintEngine: Should no longer be called”
Forum Update on Monday, May 27th 2025

Unable to paint on Qt Widget, shows error “paintEngine: Should no longer be called”

Scheduled Pinned Locked Moved General and Desktop
qt5.5qwidgetscribblingqpainterqwindow
14 Posts 4 Posters 31.5k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • Chris KawaC Chris Kawa

    You are calling drawFirstPoint and drawSecondPoint from within mousePressEvent. Don't do that. The only place you should create and use a painter is inside paintEvent. Instead of drawing from mouse event store the data to draw (the position and which button was pressed) and call update(). This will schedule a paint event, inside of which you can check the data and paint what's needed.

    Btw:

    void paintEvent(QPaintEvent *event);
    void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
    

    Be consistent. If you use Q_DECL_OVERRIDE on one override (good!), use it on all of them.

    B Offline
    B Offline
    beginMyCoding
    wrote on last edited by beginMyCoding
    #3

    @Chris-Kawa Thanks for the suggestion, i am inspired from the qt example scribble in doing my program, in that example the painter is created and used in drawLineTo and updated. Do you know how that works?

    I also tried to modify my program accordingly as you said but its getting complicated for me, maybe i am doing mistakes.

    One more question, what is the difference in these two below errors?

    QPainter::begin: Paint device returned engine == 0, type: 3
    

    and

    QPainter::begin: Paint device returned engine == 0, type: 1
    
    1 Reply Last reply
    0
    • mrjjM Offline
      mrjjM Offline
      mrjj
      Lifetime Qt Champion
      wrote on last edited by
      #4

      hi
      The Scribble example draws to a image

      void ScribbleArea::drawLineTo(const QPoint &endPoint)
      {
      QPainter painter(&image); << to image
      ...
      }

      and then it paints that image in paint
      void ScribbleArea::paintEvent(QPaintEvent *event)
      {
      QPainter painter(this);
      QRect dirtyRect = event->rect();
      painter.drawImage(dirtyRect, image, dirtyRect); << draw image
      }

      To avoid drawing whole picture each time, it uses the event->rect();
      that tells which area need repainting.
      This are is set by drawLineTo.

      B 1 Reply Last reply
      1
      • mrjjM mrjj

        hi
        The Scribble example draws to a image

        void ScribbleArea::drawLineTo(const QPoint &endPoint)
        {
        QPainter painter(&image); << to image
        ...
        }

        and then it paints that image in paint
        void ScribbleArea::paintEvent(QPaintEvent *event)
        {
        QPainter painter(this);
        QRect dirtyRect = event->rect();
        painter.drawImage(dirtyRect, image, dirtyRect); << draw image
        }

        To avoid drawing whole picture each time, it uses the event->rect();
        that tells which area need repainting.
        This are is set by drawLineTo.

        B Offline
        B Offline
        beginMyCoding
        wrote on last edited by
        #5

        @mrjj thanks for your kind reply, I understood what you explained and wanted to try the scribble example. I made a test program to check the scribble example by using Qt Widget creator. I made widget using ui class and the inside code is completely from scribble example but modified. This time i am getting the error as

        QPainter::begin: Paint device returned engine == 0, type: 3
        

        Can you please find the problem. This is my code

        mainwindow.h

        #ifndef MAINWINDOW_H
        #define MAINWINDOW_H
        
        #include <QMainWindow>
        #include "inputwindow.h"
        #include "outputwindow.h"
        #include <QFileDialog>
        #include <QInputDialog>
        #include <QColorDialog>
        #include <QtGui>
        #include <QtCore>
        #include <QPoint>
        #include <QImage>
        
        namespace Ui {
        class MainWindow;
        class Inputwindow;
        }
        
        class MainWindow : public QMainWindow
        {
            Q_OBJECT
        
        public:
            explicit MainWindow(QWidget *parent = 0);
            ~MainWindow();
            QImage image;
            QColor penColor() const { return newPenColor; }
            int penWidth() const { return newPenWidth; }
        
        public slots:
        
        private slots:
            void on_open_clicked();
        
            void on_penwidth_clicked();
        
            void on_pencolor_clicked();
        
        private:
            Ui::MainWindow *ui;
            Inputwindow *inputwindow;
            int newPenWidth;
            QColor newPenColor;
        };
        
        #endif // MAINWINDOW_H
        

        inputwindow.h

        #ifndef INPUTWINDOW_H
        #define INPUTWINDOW_H
        
        #include <QWidget>
        #include <QHBoxLayout>
        
        namespace Ui {
        class Inputwindow;
        }
        
        class Inputwindow : public QWidget
        {
            Q_OBJECT
        
        public:
            explicit Inputwindow(QWidget *parent = 0);
            ~Inputwindow();
            QImage image;
            bool open(const QString &fileName);
            bool isModified() const { return modified; }
            QColor penColor() const { return newPenColor; }
            int penWidth() const { return newPenWidth; }
        
        protected:
            void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
            void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
            void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
            void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE;
        
        private slots:
        
        private:
            Ui::Inputwindow *ui;
        
            bool modified;
            bool scribbling;
            QPoint lastPoint;
            int newPenWidth;
            QColor newPenColor;
            void drawLineTo(const QPoint &endPoint);
        };
        
        #endif // INPUTWINDOW_H
        
        

        mainwindow.cpp

        #include "mainwindow.h"
        #include "ui_mainwindow.h"
        #include "inputwindow.h"
        
        MainWindow::MainWindow(QWidget *parent) :
            QMainWindow(parent),
            ui(new Ui::MainWindow)
        {
            ui->setupUi(this);
            //setCentralWidget(inputwindow);
        }
        
        MainWindow::~MainWindow()
        {
            delete ui;
        }
        
        
        
        void MainWindow::on_open_clicked()
        {
            QString fileName = QFileDialog::getOpenFileName(this, tr("choose"), "", tr("Image(*.png *.jpg *.jpeg *.bmp *.gif)"));
               if (QString::compare(fileName, QString())!=0)
               {
                       inputwindow = new Inputwindow(this);
                       inputwindow->setGeometry(QRect(QPoint(10,50),QSize(690,400)));
                       inputwindow->open(fileName);
                       inputwindow->show();
        
               }
        }
        
        void MainWindow::on_penwidth_clicked()
        {
            bool ok;
            int newWidth = QInputDialog::getInt(this, tr("Scribble"),
                                                tr("Select pen width:"),
                                                this->penWidth(), 1, 50, 1, &ok);
            if (ok)
                newPenWidth = newWidth;
        }
        
        void MainWindow::on_pencolor_clicked()
        {
            QColor newColor = QColorDialog::getColor(this->penColor());
            if (newColor.isValid())
                newPenColor = newColor;
        }
        

        inputwindow.cpp

        #include "inputwindow.h"
        #include "ui_inputwindow.h"
        #include <QtWidgets>
        
        Inputwindow::Inputwindow(QWidget *parent) :
            QWidget(parent),
            ui(new Ui::Inputwindow)
        {
            ui->setupUi(this);
            setAttribute(Qt::WA_StaticContents);
            modified = false;
            scribbling = false;
            newPenWidth = 1;
            newPenColor = Qt::blue;
        }
        
        Inputwindow::~Inputwindow()
        {
            delete ui;
        }
        
        bool Inputwindow::open(const QString &fileName)
        {
            QImage image;
            bool valid = image.load(fileName);
            if (valid)
            {
            image = image.scaledToWidth(ui->label->width(), Qt::SmoothTransformation);
            ui->label->setPixmap(QPixmap::fromImage(image));
            update();
            return true;
            }
            else
            {
                //Error handling
            }
        }
        
        
        
        void Inputwindow::paintEvent(QPaintEvent *event)
        {
            QPainter painter(this);
            QRect dirtyRect = event->rect();
            painter.drawImage(dirtyRect, image, dirtyRect);
        }
        
        void Inputwindow::mousePressEvent(QMouseEvent *event)
        {
            scribbling = true;
            if (event->button() == Qt::LeftButton) {
                lastPoint = event->pos();
                scribbling = true;
            }
        }
        
        void Inputwindow::mouseMoveEvent(QMouseEvent *event)
        {
            if ((event->buttons() & Qt::LeftButton) && scribbling)
                drawLineTo(event->pos());
        }
        
        void Inputwindow::mouseReleaseEvent(QMouseEvent *event)
        {
            if (event->button() == Qt::LeftButton && scribbling) {
                drawLineTo(event->pos());
                scribbling = false;
            }
        }
        
        void Inputwindow::drawLineTo(const QPoint &endPoint)
        {
            QPainter painter(&image);
            painter.setPen(QPen(newPenColor, newPenWidth, Qt::SolidLine, Qt::RoundCap,
                                Qt::RoundJoin));
            painter.drawLine(lastPoint, endPoint);
            modified = true;
        
            int rad = (newPenWidth / 2) + 2;
            update(QRect(lastPoint, endPoint).normalized()
                                             .adjusted(-rad, -rad, +rad, +rad));
            lastPoint = endPoint;
        }
        
        1 Reply Last reply
        0
        • mrjjM Offline
          mrjjM Offline
          mrjj
          Lifetime Qt Champion
          wrote on last edited by
          #6

          @beginMyCoding said:

          drawLineTo

          There you use image variable.
          Where is image created/set a size for the image.
          This error could be due to image having no size.
          Im not sure its the case, but easy to test
          could you try qDebug() <<"img:" << image.isNull() ;

          B 2 Replies Last reply
          1
          • mrjjM mrjj

            @beginMyCoding said:

            drawLineTo

            There you use image variable.
            Where is image created/set a size for the image.
            This error could be due to image having no size.
            Im not sure its the case, but easy to test
            could you try qDebug() <<"img:" << image.isNull() ;

            B Offline
            B Offline
            beginMyCoding
            wrote on last edited by
            #7

            @mrjj said:

            qDebug() <<"img:" << image.isNull() ;

            where should i test that function? In inputWindow?

            1 Reply Last reply
            0
            • mrjjM mrjj

              @beginMyCoding said:

              drawLineTo

              There you use image variable.
              Where is image created/set a size for the image.
              This error could be due to image having no size.
              Im not sure its the case, but easy to test
              could you try qDebug() <<"img:" << image.isNull() ;

              B Offline
              B Offline
              beginMyCoding
              wrote on last edited by
              #8

              @mrjj I created a widget window (inputwindow) to load image and use painter to draw on that image

              mrjjM 1 Reply Last reply
              0
              • B beginMyCoding

                @mrjj I created a widget window (inputwindow) to load image and use painter to draw on that image

                mrjjM Offline
                mrjjM Offline
                mrjj
                Lifetime Qt Champion
                wrote on last edited by mrjj
                #9

                @beginMyCoding
                Im still not 100% sure u set the image

                you have defined in
                class Inputwindow : public QWidget
                {
                public:
                QImage image; <<<< -- this one is used in Inputwindow::drawLineTo
                xxx

                and you do in Inputwindow::open
                ui->label->setPixmap(QPixmap::fromImage(image));
                but this "image" is local variable.
                so that is a Label having the image and the "other image " frm .h is not used. ?

                or does the massive scrolling confuse my brain ?

                --
                qDebug() <<"img:" << image.isNull() ;
                in paintevent

                B 1 Reply Last reply
                1
                • mrjjM mrjj

                  @beginMyCoding
                  Im still not 100% sure u set the image

                  you have defined in
                  class Inputwindow : public QWidget
                  {
                  public:
                  QImage image; <<<< -- this one is used in Inputwindow::drawLineTo
                  xxx

                  and you do in Inputwindow::open
                  ui->label->setPixmap(QPixmap::fromImage(image));
                  but this "image" is local variable.
                  so that is a Label having the image and the "other image " frm .h is not used. ?

                  or does the massive scrolling confuse my brain ?

                  --
                  qDebug() <<"img:" << image.isNull() ;
                  in paintevent

                  B Offline
                  B Offline
                  beginMyCoding
                  wrote on last edited by
                  #10

                  @mrjj said:

                  qDebug() <<"img:" << image.isNull() ;

                  This is what i am getting when i use

                  qDebug() <<"img:" << image.isNull() ;

                  in paintEvent

                  img: true
                  img: true
                  img: true
                  img: true
                  img: true
                  img: true
                  img: true
                  img: true
                  QPainter::begin: Paint device returned engine == 0, type: 3
                  QPainter::setPen: Painter not active
                  img: true
                  img: true
                  img: true
                  
                  1 Reply Last reply
                  0
                  • jsulmJ Offline
                    jsulmJ Offline
                    jsulm
                    Lifetime Qt Champion
                    wrote on last edited by
                    #11

                    As @mrjj already said you load your image into a local variable in open():

                    bool Inputwindow::open(const QString &fileName)
                    {
                        QImage image; <-- this one is not the one you use later!
                        bool valid = image.load(fileName);
                        if (valid)
                        {
                        image = image.scaledToWidth(ui->label->width(), Qt::SmoothTransformation);
                        ui->label->setPixmap(QPixmap::fromImage(image));
                        update();
                        return true;
                        }
                        else
                        {
                            //Error handling
                        }
                    }
                    

                    That means your QImage image in InputWindow is not set! Remove this line in open():

                    QImage image;
                    

                    https://forum.qt.io/topic/113070/qt-code-of-conduct

                    B 1 Reply Last reply
                    1
                    • jsulmJ jsulm

                      As @mrjj already said you load your image into a local variable in open():

                      bool Inputwindow::open(const QString &fileName)
                      {
                          QImage image; <-- this one is not the one you use later!
                          bool valid = image.load(fileName);
                          if (valid)
                          {
                          image = image.scaledToWidth(ui->label->width(), Qt::SmoothTransformation);
                          ui->label->setPixmap(QPixmap::fromImage(image));
                          update();
                          return true;
                          }
                          else
                          {
                              //Error handling
                          }
                      }
                      

                      That means your QImage image in InputWindow is not set! Remove this line in open():

                      QImage image;
                      
                      B Offline
                      B Offline
                      beginMyCoding
                      wrote on last edited by
                      #12

                      @jsulm Hi
                      Thanks for you reply..
                      I removed the line QImage image as you mentioned. I got rid of the errors but its not painting if i try to paint on the Image. I wanted to paint on the image loaded in inputwindow.
                      Do you know what mistake i am making?

                      1 Reply Last reply
                      0
                      • mrjjM Offline
                        mrjjM Offline
                        mrjj
                        Lifetime Qt Champion
                        wrote on last edited by
                        #13

                        Hi
                        Maybe the label is covering up the image.

                        ui->label->setPixmap(QPixmap::fromImage(image));

                        This shows a copy of the image on screen. (not the one u draw on)
                        Try to remove it and see if that makes difference.

                        B 1 Reply Last reply
                        1
                        • mrjjM mrjj

                          Hi
                          Maybe the label is covering up the image.

                          ui->label->setPixmap(QPixmap::fromImage(image));

                          This shows a copy of the image on screen. (not the one u draw on)
                          Try to remove it and see if that makes difference.

                          B Offline
                          B Offline
                          beginMyCoding
                          wrote on last edited by
                          #14

                          @mrjj yeah!! its working bro if i remove label.. Thank you all for your suggestions

                          1 Reply Last reply
                          1

                          • Login

                          • Login or register to search.
                          • First post
                            Last post
                          0
                          • Categories
                          • Recent
                          • Tags
                          • Popular
                          • Users
                          • Groups
                          • Search
                          • Get Qt Extensions
                          • Unsolved