"QPainter::drawRects: Painter not active "错误C++/QT

"QPainter::drawRects: Painter not active " error C++/QT

本文关键字:C++ 错误 QT not QPainter drawRects Painter active      更新时间:2023-10-16

我是Qt的初学者和c++,我想看看如何在Qt中使用QPainter和事件,但由于执行过程中出现错误消息,我被卡住了,我的原始代码:

主.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();
}

标题:

#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中,但在我的代码中不是这样,谢谢你的帮助。

  1. 你只需要一个画家。第二个没有激活,而且你根本不需要它。

  2. 永远不要调用repaint(),除非你以某种方式绝对需要在repaint()返回之前完成绘制(这就是发生的事情!(。如果您保持事件循环正常运行,就永远不需要它。

  3. 不要从paintEvent()调用update():这是无稽之谈。

  4. 当您希望重新绘制小部件时,调用update():它从事件循环中调度更新。多个未完成的更新被合并,以保持事件循环的功能并防止事件风暴。

  5. 让编译器为您生成更多内存管理代码。你已经通过使用智能指针完成了第一步——这很好。现在执行第二个操作:按值保存CustomWidget的实例。它不必显式地动态分配。C++不是C,你可以利用价值。

  6. 在一个简单的测试用例中,您不需要三个文件。您的代码应该在一个main.cpp中放入尽可能少的行。如果由于Q_OBJECT宏需要对文件进行moc,请在末尾添加#include "main.moc",然后在项目上重新运行qmake以注意它。

在修复了问题之后,这样的测试用例应该是这样的。记住:这是一个测试用例,而不是100kLOC项目。您不需要也不希望分布在三个文件中的35行代码。此外,通过分散代码,你会让自己更难理解。

即使在大型项目中,除非相反,您可以显示出显著的构建时改进,否则您可以在头文件中完全实现大量Java风格的小类。这是C++中唯一的Java风格。

// https://github.com/KubaO/stackoverflown/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();
}

当用于创建QPainter(QPixmap)QPixmap无效时(如果该路径上没有文件(,也可能发生此错误。

QPixmap上作画之前,请确保其正确无误。