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 32.3k 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.
  • 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