[英]Unable to paint on Qt Widget, shows error “paintEngine: Should no longer be called”
I have created a widget using Qt Creator such a way that it has two sub windows inside a main window and some push buttons to load, save images, set pen width and color to paint on the window. 我使用Qt Creator创建了一个小部件,它在主窗口内有两个子窗口,一些按钮可以加载,保存图像,设置笔宽和颜色以在窗口上绘画。 But when i start to paint it gives me error saying 但是,当我开始绘画时,它给我错误的说法
QWidget::paintEngine: Should no longer be called
QPainter::begin: Paint device returned engine == 0, type: 1
QPainter::setPen: Painter not active
QPainter::drawPoints: Painter not active
Does anyone know what mistake i am doing, i checked threads related to this topic but could not find suitable solution. 有谁知道我在做什么错,我检查了与此主题相关的线程但找不到合适的解决方案。 I am also new to c++, so please help me to find a solution 我也是c ++的新手,所以请帮我找一个解决方案
This is my code below 这是我的代码
widget.h widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QtCore>
#include <QImage>
#include <QColor>
#include <QPoint>
#include <QtGui>
#include <QPainter>
#include <QMainWindow>
#include <QFileDialog>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
bool isModified() const { return modified; }
QColor penColor() const { return newPenColor; }
int penWidth() const { return newPenWidth; }
protected:
void paintEvent(QPaintEvent *event);
void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
private slots:
void on_open_clicked();
void on_save_clicked();
void on_penWidth_clicked();
void on_penColor_clicked();
private:
Ui::Widget *ui;
QImage image;
QPixmap imageobject;
int newPenWidth;
QColor newPenColor;
bool modified;
bool scribbling;
QPoint firstPoint, secondPoint;
void drawFirstPoint(const QPoint);
void drawSecondPoint(const QPoint);
};
#endif // WIDGET_H
main.cpp main.cpp中
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
widget.cpp widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QtWidgets>
#ifndef QT_NO_PRINTER
#include <QtPrintSupport/QPrinter>
#include <QtPrintSupport/QPrintDialog>
#endif
#include <QLabel>
#include <QWidget>
Widget::Widget(QWidget *parent) : QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
setAttribute(Qt::WA_StaticContents);
modified = false;
scribbling = false;
newPenWidth = 1;
newPenColor = Qt::blue;
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_open_clicked()
{
QString filename = QFileDialog::getOpenFileName(this, tr("choose"), "", tr("Image(*.png *.jpg *.jpeg *.bmp *.gif)"));
if (QString::compare(filename, QString())!=0)
{
QImage image;
bool valid = image.load(filename);
if (valid)
{
image = image.scaledToWidth(ui->inputWindow->width(), Qt::SmoothTransformation);
ui->inputWindow->setPixmap(QPixmap::fromImage(image));
image = image.scaledToWidth(ui->outputWindow->width(), Qt::SmoothTransformation);
ui->outputWindow->setPixmap(QPixmap::fromImage(image));
}
else
{
//Error handling
}
}
}
void Widget::on_save_clicked()
{
QString filename = QFileDialog::getSaveFileName(this,tr("choose"), "", tr("PNG (*.png);; JPEG (*.jpg *.jpeg);; BMP(*.bmp);; GIF(*.gif)"));
QImage imageobject = image;
imageobject.save(filename);
}
void Widget::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
QRect dirtyRect = event->rect();
painter.drawImage(dirtyRect, image, dirtyRect);
}
void Widget::mousePressEvent(QMouseEvent *event)
{
scribbling = true;
if (event->button() == Qt::LeftButton && scribbling)
{
firstPoint = event->pos();
drawFirstPoint(firstPoint);
}
else if (event->button() == Qt::RightButton && scribbling) {
secondPoint = event->pos();
drawSecondPoint(secondPoint);
}
}
void Widget::drawFirstPoint(const QPoint)
{
QPainter painter(this);
painter.setPen(QPen(newPenColor, newPenWidth, Qt::SolidLine, Qt::RoundCap,
Qt::RoundJoin));
painter.drawPoint(firstPoint);
modified = true;
int rad = (newPenWidth / 2) + 2;
update(QRect(firstPoint, firstPoint).normalized().adjusted(-rad, -rad, +rad, +rad));
}
void Widget::drawSecondPoint(const QPoint)
{
QPainter painter(this);
painter.setPen(QPen(newPenColor, newPenWidth, Qt::SolidLine, Qt::RoundCap,
Qt::RoundJoin));
painter.drawPoint(secondPoint);
modified = true;
int rad = (newPenWidth / 2) + 2;
update(QRect(secondPoint, secondPoint).normalized().adjusted(-rad, -rad, +rad, +rad));
}
void Widget::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 Widget::on_penColor_clicked()
{
QColor newColor = QColorDialog::getColor(this->penColor());
if (newColor.isValid())
newPenColor = newColor;
}
widget.ui widget.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Widget</class>
<widget class="QWidget" name="Widget">
<property name="enabled">
<bool>true</bool>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1300</width>
<height>700</height>
</rect>
</property>
<property name="windowTitle">
<string>Test window</string>
</property>
<property name="layoutDirection">
<enum>Qt::LeftToRight</enum>
</property>
<widget class="QLabel" name="inputWindow">
<property name="geometry">
<rect>
<x>40</x>
<y>120</y>
<width>600</width>
<height>500</height>
</rect>
</property>
<property name="maximumSize">
<size>
<width>600</width>
<height>16777215</height>
</size>
</property>
<property name="cursor">
<cursorShape>CrossCursor</cursorShape>
</property>
<property name="text">
<string>TextLabel</string>
</property>
</widget>
<widget class="QLabel" name="outputWindow">
<property name="geometry">
<rect>
<x>660</x>
<y>120</y>
<width>600</width>
<height>500</height>
</rect>
</property>
<property name="maximumSize">
<size>
<width>600</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>TextLabel</string>
</property>
</widget>
<widget class="QWidget" name="layoutWidget">
<property name="geometry">
<rect>
<x>170</x>
<y>10</y>
<width>651</width>
<height>31</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="open">
<property name="cursor">
<cursorShape>PointingHandCursor</cursorShape>
</property>
<property name="text">
<string>OPEN</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="save">
<property name="cursor">
<cursorShape>PointingHandCursor</cursorShape>
</property>
<property name="text">
<string>SAVE</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="penWidth">
<property name="text">
<string>Pen Width</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="penColor">
<property name="text">
<string>Pen Color</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_5">
<property name="text">
<string>PushButton</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>
All painting on a widget must happen in the paintEvent()
function, and you are trying to paint outside of it - that won't work. 窗口小部件上的所有绘制必须在paintEvent()
函数中进行,并且您尝试在其外部绘制 - 这将无法工作。
You must either find a way to put all your drawing calls inside the paintEvent()
function, or draw on a buffer, for example a QPixmap
and then draw that pixmap onto the widget in the paintEvent()
When you draw on a buffer you can draw from everywhere, the limitation is only for widget drawing. 您必须找到一种方法将所有绘图调用放在paintEvent()
函数中,或绘制缓冲区,例如QPixmap
,然后将该pixmap绘制到paintEvent()
的小部件paintEvent()
您在缓冲区上绘制时,您可以从任何地方抽取,限制仅适用于小部件绘图。 For pixmaps you (usually) must draw from the main thread, if you want to draw from another thread, use QImage
instead. 对于pixmaps,你(通常)必须从主线程绘制,如果你想从另一个线程绘制,请使用QImage
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.