Unable to paint on Qt Widget, shows error “paintEngine: Should no longer be called”
-
hi
The Scribble example draws to a imagevoid 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. -
@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 fromscribble
example but modified. This time i am getting the error asQPainter::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; }
-
@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() ; -
@beginMyCoding
Im still not 100% sure u set the imageyou have defined in
class Inputwindow : public QWidget
{
public:
QImage image; <<<< -- this one is used in Inputwindow::drawLineTo
xxxand 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 -
@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
-
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;
-
@jsulm Hi
Thanks for you reply..
I removed the lineQImage 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? -
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.