"QPainter::drawRects: Painter not active " 错误 C++/QT
"QPainter::drawRects: Painter not active " error C++/QT
我是 Qt 的初学者
和 c++,我想看看如何在 Qt 中使用 QPainter 和事件,但由于执行过程中出现错误消息,我被卡住了,我的原始代码:
main.cpp
#include "customwidget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QScopedPointer<QWidget> widget(new customWidget());
widget->resize(240, 120);
widget->show();
return a.exec();
}
和 header:
#ifndef CUSTOMWIDGET_H
#define CUSTOMWIDGET_H
#include <QWidget>
#include <QMouseEvent>
#include <QPoint>
#include <QPainter>
class customWidget : public QWidget
{
Q_OBJECT
public:
explicit customWidget(QWidget *parent = 0);
void paintEvent(QPaintEvent *);
void mouseMoveEvent(QMouseEvent *event);
void mousePressEvent(QMouseEvent *event);
private:
QPoint m_mousePos;
QRect m_r2;
signals:
void needToRepaint();
public slots:
};
#endif // CUSTOMWIDGET_H
和.cpp:
#include "customwidget.h"
customWidget::customWidget(QWidget *parent) : QWidget(parent)
{
QRect m_r2;
QPoint m_mousePos;
QObject::connect(this, SIGNAL(needToRepaint()), this, SLOT(repaint()));
}
void customWidget::paintEvent(QPaintEvent *)
{
QPainter painter(this);
// ############ First Rectangle ****************************************
QRect r1 = rect().adjusted(10, 10, -10, -10);
painter.setPen(QColor("#FFFFFF"));
painter.drawRect(r1);
// ############ Seconde Rectangle ****************************************
QRect r2(QPoint(0, 0), QSize(100, 100));
m_r2.moveCenter(m_mousePos);
QPainter painter2;
QPen pen;
painter2.setPen(QColor("#000000"));
pen.setWidth(3);
painter2.setPen(pen);
painter2.drawRect(m_r2);
update();
}
void customWidget::mouseMoveEvent(QMouseEvent *event)
{
m_mousePos = event->pos();
emit needToRepaint();
}
我试着在网上搜索它,发现这是因为 QPainter 不在 paintEvent 中,但在我的代码中不是这样,感谢您的帮助。
你只需要一个画家。第二个没有激活,反正你也不需要。
永远不要调用 repaint()
除非你以某种方式绝对需要在 repaint()
returns 之前完成绘画(这就是发生的事情!)。如果你正确地保持事件循环 运行ning,你将永远不需要它。
不要从paintEvent()
调用update()
:这是胡说八道(字面意思)。
当您希望重新绘制小部件时,请调用 update()
:它会安排事件循环的更新。合并多个未完成的更新以保持事件循环功能并防止事件风暴。
让编译器为您生成更多内存管理代码。您已经通过使用智能指针完成了第一步 - 这很好。现在做第二个:按值保存 CustomWidget
的实例。它不必显式动态分配。 C++ 不是 C,您可以利用值。
在一个简单的测试用例中,你不需要三个文件。您的代码应包含在尽可能少的行中,在单个 main.cpp
中。如果由于 Q_OBJECT
宏需要 moc 文件,在末尾添加 #include "main.moc"
,并在项目上重新 运行 qmake 以注意它。
这是解决问题后这样的测试用例的样子。请记住:这是一个测试用例,而不是 100kLOC 项目。您不需要也不希望分布在三个文件中的 35 行代码。此外,通过散布代码,您自己会更难理解。
即使在大项目中,除非您可以显着改善构建时间,否则您可以在头文件中完全实现大量小型 类 样式 Java。那是关于 C++ 中唯一的 Java 风格的东西。
// https://github.com/KubaO/Whosebugn/tree/master/questions/simple-paint-38796140
#include <QtWidgets>
class CustomWidget : public QWidget
{
QPoint m_mousePos;
public:
explicit CustomWidget(QWidget *parent = nullptr) : QWidget{parent} {}
void paintEvent(QPaintEvent *) override;
void mouseMoveEvent(QMouseEvent *event) override {
m_mousePos = event->pos();
update();
}
};
void CustomWidget::paintEvent(QPaintEvent *)
{
QPainter painter(this);
auto r1 = rect().adjusted(10, 10, -10, -10);
painter.setPen(Qt::white);
painter.drawRect(r1);
auto r2 = QRect{QPoint(0, 0), QSize(100, 100)};
r2.moveCenter(m_mousePos);
painter.setPen(QPen{Qt::black, 3, Qt::SolidLine, Qt::SquareCap, Qt::MiterJoin});
painter.drawRect(r2);
}
int main(int argc, char ** argv) {
QApplication app{argc, argv};
CustomWidget w;
w.show();
return app.exec();
}
我是 Qt 的初学者 和 c++,我想看看如何在 Qt 中使用 QPainter 和事件,但由于执行过程中出现错误消息,我被卡住了,我的原始代码:
main.cpp
#include "customwidget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QScopedPointer<QWidget> widget(new customWidget());
widget->resize(240, 120);
widget->show();
return a.exec();
}
和 header:
#ifndef CUSTOMWIDGET_H
#define CUSTOMWIDGET_H
#include <QWidget>
#include <QMouseEvent>
#include <QPoint>
#include <QPainter>
class customWidget : public QWidget
{
Q_OBJECT
public:
explicit customWidget(QWidget *parent = 0);
void paintEvent(QPaintEvent *);
void mouseMoveEvent(QMouseEvent *event);
void mousePressEvent(QMouseEvent *event);
private:
QPoint m_mousePos;
QRect m_r2;
signals:
void needToRepaint();
public slots:
};
#endif // CUSTOMWIDGET_H
和.cpp:
#include "customwidget.h"
customWidget::customWidget(QWidget *parent) : QWidget(parent)
{
QRect m_r2;
QPoint m_mousePos;
QObject::connect(this, SIGNAL(needToRepaint()), this, SLOT(repaint()));
}
void customWidget::paintEvent(QPaintEvent *)
{
QPainter painter(this);
// ############ First Rectangle ****************************************
QRect r1 = rect().adjusted(10, 10, -10, -10);
painter.setPen(QColor("#FFFFFF"));
painter.drawRect(r1);
// ############ Seconde Rectangle ****************************************
QRect r2(QPoint(0, 0), QSize(100, 100));
m_r2.moveCenter(m_mousePos);
QPainter painter2;
QPen pen;
painter2.setPen(QColor("#000000"));
pen.setWidth(3);
painter2.setPen(pen);
painter2.drawRect(m_r2);
update();
}
void customWidget::mouseMoveEvent(QMouseEvent *event)
{
m_mousePos = event->pos();
emit needToRepaint();
}
我试着在网上搜索它,发现这是因为 QPainter 不在 paintEvent 中,但在我的代码中不是这样,感谢您的帮助。
你只需要一个画家。第二个没有激活,反正你也不需要。
永远不要调用
repaint()
除非你以某种方式绝对需要在repaint()
returns 之前完成绘画(这就是发生的事情!)。如果你正确地保持事件循环 运行ning,你将永远不需要它。不要从
paintEvent()
调用update()
:这是胡说八道(字面意思)。当您希望重新绘制小部件时,请调用
update()
:它会安排事件循环的更新。合并多个未完成的更新以保持事件循环功能并防止事件风暴。让编译器为您生成更多内存管理代码。您已经通过使用智能指针完成了第一步 - 这很好。现在做第二个:按值保存
CustomWidget
的实例。它不必显式动态分配。 C++ 不是 C,您可以利用值。在一个简单的测试用例中,你不需要三个文件。您的代码应包含在尽可能少的行中,在单个
main.cpp
中。如果由于Q_OBJECT
宏需要 moc 文件,在末尾添加#include "main.moc"
,并在项目上重新 运行 qmake 以注意它。
这是解决问题后这样的测试用例的样子。请记住:这是一个测试用例,而不是 100kLOC 项目。您不需要也不希望分布在三个文件中的 35 行代码。此外,通过散布代码,您自己会更难理解。
即使在大项目中,除非您可以显着改善构建时间,否则您可以在头文件中完全实现大量小型 类 样式 Java。那是关于 C++ 中唯一的 Java 风格的东西。
// https://github.com/KubaO/Whosebugn/tree/master/questions/simple-paint-38796140
#include <QtWidgets>
class CustomWidget : public QWidget
{
QPoint m_mousePos;
public:
explicit CustomWidget(QWidget *parent = nullptr) : QWidget{parent} {}
void paintEvent(QPaintEvent *) override;
void mouseMoveEvent(QMouseEvent *event) override {
m_mousePos = event->pos();
update();
}
};
void CustomWidget::paintEvent(QPaintEvent *)
{
QPainter painter(this);
auto r1 = rect().adjusted(10, 10, -10, -10);
painter.setPen(Qt::white);
painter.drawRect(r1);
auto r2 = QRect{QPoint(0, 0), QSize(100, 100)};
r2.moveCenter(m_mousePos);
painter.setPen(QPen{Qt::black, 3, Qt::SolidLine, Qt::SquareCap, Qt::MiterJoin});
painter.drawRect(r2);
}
int main(int argc, char ** argv) {
QApplication app{argc, argv};
CustomWidget w;
w.show();
return app.exec();
}