QPainter绘制遇到的小问题

时间:2021-12-13 17:03:51

1.Qt绘图基础

(1)绘图需画笔和画布:

  • QPainter 相当于Qt中的一个画笔,绘制时需要一块画布,
  • Qt中扮演画布角色的组件为QPaintDevice和他的各个子类,如: QWidget, QPixmap, QPixture...
  • QPainter、QPaintDevice之间使用 QPaintEngine 进行通讯(也就是翻译 QPainter 的指令的意思)

(2)怎么画

  • 通常都是要在哪个 widget 上绘图,就需要在它的 paintEvent() 函数里绘图,即重写 paintEvent() 函数

(3)实例

PaintTest.h

 #ifndef PAINTTEST_H
#define PAINTTEST_H #include <QWidget>
#include <QLabel>
#include <QPainter>
class PaintTest : public QWidget
{
Q_OBJECT
private:
QLabel *la;
public:
explicit PaintTest(QWidget *parent = );
void paintEvent(QPaintEvent *); };
#endif // PAINTTEST_H

PaintTest.cpp

 #include "PaintTest.h"
#include <QLabel>
#include <QEvent >
PaintTest::PaintTest(QWidget *parent) :
QWidget(parent),la(new QLabel(this))
{
la->setText("PaintTest Label");
la->resize(,19); la->installEventFilter(this);
}
void PaintTest::paintEvent(QPaintEvent *) {
QPainter painter(this); // this 是 PaintTest 的指针
painter.setPen(Qt::gray);
painter.setBrush(Qt::green);
painter.drawRect(, , , );
}

main.cpp

 #include <QApplication>

 #include "PaintTest.h"

 int main(int argc,char* argv[])
{
QApplication a(argc, argv); PaintTest pt;
pt.show(); return a.exec();
}

QPainter绘制遇到的小问题

2.遇到的问题

如果行绘制的图形是在Qwidget的子的组件上应该怎么绘制在哪里绘制?

一般想到的是直接在paintEvent()更改

 void PaintTest::paintEvent(QPaintEvent *) {
// QPainter painter(this); // this 是 PaintTest 的指针
QPainter painter(this->la);
painter.setPen(Qt::gray);
painter.setBrush(Qt::green);
painter.drawRect(, , , );
}

运行程序,结果并没有在 Label 上绘制出矩形,而且还输出了下面的错误:

QPainter::begin: Paint device returned engine == , type:
QPainter::setPen: Painter not active
QPainter::setBrush: Painter not active
QPainter::drawRects: Painter not active
QPainter::begin: Paint device returned engine == , type:

上面1(2)提到了想要在哪个 widget 上绘图,就需要在它的 paintEvent() 函数里绘图,这里我们是想在这个Qlabel中绘图,但是paintEvent()函数是PainterTest的,所以绘制出了问题绘制不成功。

因此想要在QLabel中绘制图形,就必须新建一个类继承自QLAbel,然后在它的 paintEvent() 里绘图,如果单独就这个问题创建一个新的类就会有点小题大作了

3.解决

在事件过滤器 eventFilter() 中拦截 QLabel 的 QEvent::Paint 事件,用 QLabel 创建 QPainter,就可以在 QLabel 上绘图了

代码为

PaintTest.h

 #ifndef PAINTTEST_H
#define PAINTTEST_H #include <QWidget>
#include <QLabel>
#include <QPainter>
class PaintTest : public QWidget
{
Q_OBJECT
private:
QLabel *la;
public:
explicit PaintTest(QWidget *parent = );
// void paintEvent(QPaintEvent *);
bool eventFilter(QObject *watched, QEvent *event) ;
void magicTime();
signals: public slots: };
#endif // PAINTTEST_H

PaintTest.cpp

 #include "PaintTest.h"
#include <QLabel>
#include <QEvent >
PaintTest::PaintTest(QWidget *parent) :
QWidget(parent),la(new QLabel(this))
{
//la=new QLabel(this); la->setText("PaintTest Label");
la->resize(,); la->installEventFilter(this);
}
/*void PaintTest::paintEvent(QPaintEvent *) {
QPainter painter(this); // this 是 PaintTest 的指针
QPainter painter(this->la);
painter.setPen(Qt::gray);
painter.setBrush(Qt::green);
painter.drawRect(10, 10, 50, 50);
}*/ bool PaintTest::eventFilter(QObject *watched, QEvent *event) {
if (watched == this->la && event->type() == QEvent::Paint) {
magicTime();
} return QWidget::eventFilter(watched, event);
} void PaintTest::magicTime() {
QPainter painter(this->la );
painter.setPen(Qt::gray);
painter.setBrush(Qt::green);
painter.drawRect(, , , );
}