Невозможно нарисовать на Qt Widget, показывает ошибку & quot; paintEngine: больше не должен называться & quot;

Я создал виджет с помощью Qt Creator таким образом, что у него есть два подокна внутри главного окна и несколько кнопок для загрузки, сохранения изображений, установки ширины пера и цвета для рисования на окне.
Но когда я начинаю рисовать, это дает мне ошибку, говоря

 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

Кто-нибудь знает, какую ошибку я делаю, я проверил темы, связанные с этой темой, но не смог найти подходящего решения.
Я также новичок в C ++, поэтому, пожалуйста, помогите мне найти решение

Это мой код ниже

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

#include "widget.h"#include <QApplication>

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();

return a.exec();
}

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

<?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>

2

Решение

Все рисование на виджете должно происходить в paintEvent() функции, и вы пытаетесь рисовать за ее пределами — это не сработает.

Вы должны либо найти способ поместить все свои вызовы рисования в paintEvent() функция или рисовать на буфере, например QPixmap а затем нарисовать это растровое изображение на виджет в paintEvent() Когда вы рисуете в буфере, вы можете рисовать отовсюду, ограничение только для рисования виджетов. Для растровых изображений вы (обычно) должны рисовать из основного потока, если вы хотите рисовать из другого потока, используйте QImage вместо.

7

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]