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 = 0);
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(100,190);
la->installEventFilter(this);
}
void PaintTest::paintEvent(QPaintEvent *) {
QPainter painter(this); // this 是 PaintTest 的指针
painter.setPen(Qt::gray);
painter.setBrush(Qt::green);
painter.drawRect(10, 10, 50, 50);
}
main.cpp
#include <QApplication>
#include "PaintTest.h"
int main(int argc,char* argv[])
{
QApplication a(argc, argv);
PaintTest pt;
pt.show();
return a.exec();
}
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(10, 10, 50, 50);
}
运行程序,结果并没有在 Label 上绘制出矩形,而且还输出了下面的错误:
QPainter::begin: Paint device returned engine == 0, type: 1
QPainter::setPen: Painter not active
QPainter::setBrush: Painter not active
QPainter::drawRects: Painter not active
QPainter::begin: Paint device returned engine == 0, type: 1
上面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 = 0);
// 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(100,190);
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(10, 10, 50, 50);
}
以上是https://www.cnblogs.com/zhaobinyouth/p/9856383.html博主的,我直接用来引用(感谢博主)
我一开始是想在ui->listWidget的每一个item下面加一条横线,
QListWidget::item {
background: #152e5d;
border: 2px solid #0c4d80;
#border-radius: 0px 2px 0px 0px;
border-bottom: 1px solid blue;
}
闲着没事,试一下用painter去画一下。但是我用listWidget没有效果,不太懂,后期补
eventFilter译为拦截器,在paintEvent事件之后发生
文章不对的欢迎大佬留言,一起进步