QPainter绘制总结

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事件之后发生

文章不对的欢迎大佬留言,一起进步

  • 3
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值