首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >"QPainter::drawRects: Painter not active“错误C++/QT

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

Stack Overflow用户
提问于 2016-08-06 03:00:33
回答 1查看 19.1K关注 0票数 5

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

the main.cpp

代码语言:javascript
运行
复制
#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();
}

和报头:

代码语言:javascript
运行
复制
#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:

代码语言:javascript
运行
复制
#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中,但在我的代码中不是这样的,谢谢你的帮助。

EN

Stack Overflow用户

回答已采纳

发布于 2016-08-06 06:52:52

  1. 你只需要一个油漆工。第二个没有激活,你也不需要它。
  2. 永远不要调用repaint(),除非你绝对需要在repaint()返回之前完成绘制(这就是发生的事情!)。如果您保持事件循环正常运行,您将永远不需要它。
  3. 不要从update()调用paintEvent():这是胡说八道您希望重新绘制窗口小部件,调用update():它从事件循环调度更新。多个未完成的更新合并在一起,以保持事件循环的功能并防止事件风暴。
  4. 让编译器为您生成更多的内存管理代码。你已经通过使用智能指针完成了第一步--这很好。现在执行第二个操作:按值保留CustomWidget的实例。它不需要显式地动态分配。C++不是C语言,你可以利用values。
  5. 在一个简单的测试用例中,你不需要三个文件。您的代码应该在单个main.cpp中包含尽可能少的行。如果由于Q_OBJECT宏而需要moc该文件,请在末尾添加#include "main.moc",然后在项目上重新运行qmake以注意到它。

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

即使在大型项目中,除非您可以在相反的情况下显示出显著的构建时间改进,否则您可以在头文件中实现大量完全Java风格的小类。这大概是惟一的Java风格--任何属于C++的东西。

代码语言:javascript
运行
复制
// 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();
}
票数 4
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38796140

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档