在QLabel等控件上绘图

由于无法直接在QLabel上进行绘图,所以需要通过几种其它的方式来进行处理绘图情况

  • 通过自定义控件,然后对QLabel进行提升为自定义控件类。
  • 通过事件过滤器eventFilter来捕获绘图事件,然后进行绘图。

一、主函数中通过自定义控件绘图

1、通过自定义控件触发信号,然后在主程序的槽函数中实现绘图

  • 首先自定义控件所对应的类MyLabel,该类继承自类QLabel。
  • 在该类中自定义用于触发绘图的信号StartPaint,并在该类中重写 paintEvent()函数。
  • paintEvent()函数中来触发绘图的信号 emit StartPaint();
  • 然后在主程序中定义对应的槽函数PaintOnQLabel,用于接收到触发绘图信号StartPaint后开始在对应的QLabel上进行绘图操作。
  • UI所对应的label上进行提升,将其提升为自定义控件MyLabel

2、对应文件及代码如下
(1)、自定义控件类MyLabel,继承自QLabel

/******* MyLabel.h *******/

#pragma once
#include 
#include 

class MyLabel : public QLabel
{
    Q_OBJECT

public:
    MyLabel(QWidget *parent=nullptr);
    ~MyLabel();

protected:
    void paintEvent(QPaintEvent *event);

signals:
    void StartPaint();
};
/******* MyLabel.cpp *******/
#include "MyLabel.h"

MyLabel::MyLabel(QWidget *parent) : QLabel(parent)
{}

MyLabel::~MyLabel()
{}

void MyLabel::paintEvent(QPaintEvent *event)
{
    // 在自定义的类中来触发绘图信号
    emit StartPaint();
}

(2)、主程序 Pr04_PaintOnQLabel

/******* Pr04_PaintOnQLabel.h *******/
#pragma once

#include 
#include 
#include "ui_Pr04_PaintOnQLabel.h"
#include "MyLabel.h"

class Pr04_PaintOnQLabel : public QWidget
{
    Q_OBJECT

public:
    Pr04_PaintOnQLabel(QWidget *parent = Q_NULLPTR);

protected slots:
    void PaintOnQLabel(); //自定义用于在QLabel上绘图的槽函数

private:
    Ui::Pr04_PaintOnQLabelClass ui;
};

/******* Pr04_PaintOnQLabel.cpp *******/
#include "Pr04_PaintOnQLabel.h"
#include 
#include 

Pr04_PaintOnQLabel::Pr04_PaintOnQLabel(QWidget *parent)
    : QWidget(parent)
{
    ui.setupUi(this);

    connect(ui.label_01, &MyLabel::StartPaint, this, &Pr04_PaintOnQLabel::PaintOnQLabel);
}

void Pr04_PaintOnQLabel::PaintOnQLabel()
{
    QPainter painter(ui.label_01);

    painter.setBrush(Qt::blue);
    painter.drawPie(QRect(0, 0, ui.label_01->width(), ui.label_01->height()), 0, 280 * 16);
}

3、运行结果如下
在QLabel等控件上绘图_第1张图片

4、注意事项:函数的执行顺序

  • 首先是自定义控件类MyLabel的构造函数初始化
  • 然后是主程序类 Pr04_PaintOnQLabel的构造函数初始化
  • 再是自定义控件类MyLabel的 paintEvent 函数执行
  • 最后是主程序类 Pr04_PaintOnQLabel的槽函数在接收到信号之后进行绘图操作

二、自定义控件类中直接在paintEvent中绘图

1、过程分析

  • 该方法同样是需要将控件QLabel提升为对应的自定义控件
  • 由以上可知,程序的执行顺序。在执行自定义类中paintEvent之前已经将所有的UI初始化了,各控件的尺寸得到了修正。所以可以直接在painEvent函数中直接进行绘图
  • 该方法不需要再到主函数中通过信号槽连接的方式,在槽函数中进行绘图。相对而言会更加简洁

2、对应代码如下,主程序为默认,不进行绘图操作

/******* MyLabel.h *******/
#pragma once
#include 
#include 

class MyLabel : public QLabel
{
    Q_OBJECT

public:
    MyLabel(QWidget *parent=nullptr);
    ~MyLabel();

protected:
    void paintEvent(QPaintEvent *event);

private:
    int w0; //自定义控件类构造函数中QLabel宽度,为默认值
    int h0; //自定义控件类构造函数中QLabel高度,为默认值
};
/******* MyLabel.cpp *******/
#include "MyLabel.h"
#include 
#include 

MyLabel::MyLabel(QWidget *parent) : QLabel(parent)
{
    //此处值为默认初始值
    w0 = this->width(); 
    h0 = this->height();  
}

MyLabel::~MyLabel()
{}

//直接在paintEvent函数中进行绘图,无需再触发信号来进行绘图。
void MyLabel::paintEvent(QPaintEvent *event)
{
    //此处值为执行主程序中后修正过的值
    int w = this->width();
    int h = this->height();

    QPainter painter(this);
    painter.setPen(QPen(Qt::red, 8));
    painter.drawLine(0, 0, w, h);
    painter.drawPie(QRect(10, 10, w - 10, h - 10), 0, 315 * 16);
}

3、结果如下图
在QLabel等控件上绘图_第2张图片



三、直接在事件过滤器中进行绘图操作

1、过程分析

  • 绘图操作一般要在paintEvent事件函数中去进行处理,因为绘图操作被event分发到paintEvent中去进行处理了。
  • 由于QLabel等控件的绘图事件会被Qt默认过滤掉,因此一般不能直接在QLabel等控件上进行绘图。
  • 对于直接在QLabel上进行绘图操作,就可以通过事件过滤器eventFilter或者事件函数event来对QLabel控件的绘图事件进行捕获,并在捕获到绘图事件QEvent::Paint 后进行绘图操作。
  • 该绘图操作就不需要在paintEvent事件函数中进行处理了,可以自定义绘图函数来进行处理。

2、在QLabel上通过捕获绘图事件来进行绘图操作

(1)、Pr04_PaintOnQLabel文件对应代码如下

/******* Pr04_PaintOnQLabel.h *******/
#pragma once
#include 
#include "ui_Pr04_PaintOnQLabel.h"

class Pr04_PaintOnQLabel : public QWidget
{
    Q_OBJECT
public:
    Pr04_PaintOnQLabel(QWidget *parent = Q_NULLPTR);

protected:
   bool eventFilter(QObject *watched, QEvent *event);//事件过滤器
   void StartDraw(); //捕获到绘图事件后,就开始绘图操作。

private:
    Ui::Pr04_PaintOnQLabelClass ui;
};

/******* Pr04_PaintOnQLabel.cpp *******/
#include "Pr04_PaintOnQLabel.h"
#include 

Pr04_PaintOnQLabel::Pr04_PaintOnQLabel(QWidget *parent)
    : QWidget(parent)
{
    ui.setupUi(this);
    //在需要过滤操作的控件上安装事件过滤器
    ui.label_02->installEventFilter(this);
}

bool Pr04_PaintOnQLabel::eventFilter(QObject *watched, QEvent *event)
{
    if (watched == ui.label_02 && event->type()==QEvent::Paint)
    {
        StartDraw();
        return true;
    }
    else
    {
        return QWidget::eventFilter(watched, event);
    }
}

void Pr04_PaintOnQLabel::StartDraw()
{
    QPainter painter(ui.label_02);

    painter.setPen(QPen(Qt::red, 6));
    painter.setBrush(QColor(0, 200, 200, 200));
    painter.drawPie(QRect(20, 20, ui.label_02->width() - 20, ui.label_02->height() - 20), 0, 300 * 16);

}

(2)、结果如下图
在QLabel等控件上绘图_第3张图片

你可能感兴趣的:(Qt)