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

时间:2016-08-05 19:00:33

标签: c++ qt qpainter qevent

大家好,我是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();
}

和标题:

#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 个答案:

答案 0 :(得分:1)

  1. 你只需要一位画家。第二个没有被激活,你无论如何也不需要它。

  2. 除非你以某种方式绝对需要在repaint()返回之前完成绘画(那就是发生了什么!),否则不要打电话给repaint()。如果你保持事件循环正常运行,你就不会需要它。

  3. 不要从update()致电paintEvent():这是废话(确切地说)。

  4. 如果要重新绘制窗口小部件,请调用update():它会调度事件循环中的更新。合并多个未完成的更新以保持事件循环功能并防止事件风暴。

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

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

  7. 在解决问题之后,这就是这样一个测试用例的样子。请记住:它是一个测试用例,而不是一个100kLOC项目。您不需要也不希望将35行代码分布在三个文件中。此外,通过展开代码,你可以让自己更难理解。

    即使在大型项目中,除非你能够显示相当大的构建时间,否则你可以在头文件中完全实现Java风格的大量小类。这是关于唯一的Java风格 - 任何属于C ++的东西。

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