Я создал виджет с помощью 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>
Все рисование на виджете должно происходить в paintEvent()
функции, и вы пытаетесь рисовать за ее пределами — это не сработает.
Вы должны либо найти способ поместить все свои вызовы рисования в paintEvent()
функция или рисовать на буфере, например QPixmap
а затем нарисовать это растровое изображение на виджет в paintEvent()
Когда вы рисуете в буфере, вы можете рисовать отовсюду, ограничение только для рисования виджетов. Для растровых изображений вы (обычно) должны рисовать из основного потока, если вы хотите рисовать из другого потока, используйте QImage
вместо.
Других решений пока нет …