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 Updated to NodeBB v4.3 + New Features

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.7k Views 2 Watching
  • 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.
  • C Offline
    C Offline
    Chris Kawa
    Lifetime Qt Champion
    wrote on 29 Feb 2016, 21:05 last edited by Chris Kawa
    #2

    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 1 Reply Last reply 1 Mar 2016, 12:52
    1
    • C Chris Kawa
      29 Feb 2016, 21:05

      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 1 Mar 2016, 12:52 last edited by beginMyCoding 3 Jan 2016, 12:55
      #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
      • M Offline
        M Offline
        mrjj
        Lifetime Qt Champion
        wrote on 1 Mar 2016, 13:02 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 Mar 2016, 21:15
        1
        • M mrjj
          1 Mar 2016, 13:02

          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 1 Mar 2016, 21:15 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
          • M Offline
            M Offline
            mrjj
            Lifetime Qt Champion
            wrote on 1 Mar 2016, 21:42 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 Mar 2016, 22:01
            1
            • M mrjj
              1 Mar 2016, 21:42

              @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 1 Mar 2016, 22:01 last edited by
              #7

              @mrjj said:

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

              where should i test that function? In inputWindow?

              1 Reply Last reply
              0
              • M mrjj
                1 Mar 2016, 21:42

                @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 1 Mar 2016, 22:17 last edited by
                #8

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

                M 1 Reply Last reply 1 Mar 2016, 22:23
                0
                • B beginMyCoding
                  1 Mar 2016, 22:17

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

                  M Offline
                  M Offline
                  mrjj
                  Lifetime Qt Champion
                  wrote on 1 Mar 2016, 22:23 last edited by mrjj 3 Jan 2016, 22:25
                  #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 2 Mar 2016, 00:51
                  1
                  • M mrjj
                    1 Mar 2016, 22:23

                    @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 2 Mar 2016, 00:51 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
                    • J Offline
                      J Offline
                      jsulm
                      Lifetime Qt Champion
                      wrote on 2 Mar 2016, 05:38 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 2 Mar 2016, 10:00
                      1
                      • J jsulm
                        2 Mar 2016, 05:38

                        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 2 Mar 2016, 10:00 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
                        • M Offline
                          M Offline
                          mrjj
                          Lifetime Qt Champion
                          wrote on 2 Mar 2016, 12:20 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 2 Mar 2016, 16:00
                          1
                          • M mrjj
                            2 Mar 2016, 12:20

                            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 2 Mar 2016, 16:00 last edited by
                            #14

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

                            1 Reply Last reply
                            1

                            11/14

                            2 Mar 2016, 05:38

                            • Login

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