文章目录
- 【1】eventFilter使用简介
- 【2】QPainter使用简介
- 【3】QPainter绘制温度案例
- 头文件
- 源文件
 
- 【4】 UI界面设计
- 【5】温度绘制图
【1】eventFilter使用简介
Qt的eventFilter是一个事件过滤器,可以用来捕获和处理Qt对象的事件。事件过滤器可以被安装到一个对象上,以便在该对象上拦截和处理包含特定类型和内容的事件。下面是eventFilter的简单使用介绍:
- 创建一个类,并继承自QObject。这个类将作为事件过滤器的实现。
- 在该类中,重写eventFilter函数。eventFilter函数接收两个参数:QObject* watched和QEvent* event,用于捕获事件和处理事件。- 参数watched是事件发送方的指针,可以用来检查事件发送方的类型或属性。
- 参数event是要处理的事件对象,可以用于检查事件类型和内容,并采取相应的处理措施。
 
- 参数
- 在需要安装事件过滤器的Qt对象上调用installEventFilter函数,将事件过滤器实例添加到该对象。
- 在事件过滤器的eventFilter函数中,检查event参数的事件类型,并处理感兴趣的事件。可以返回true来指示事件被过滤,停止传递给目标对象;或返回false以允许事件继续传递给目标对象。
下面是一个简单的示例,展示了如何使用eventFilter:
#include <QObject>
#include <QEvent>
class MyEventFilter : public QObject
{
    Q_OBJECT
public:
    explicit MyEventFilter(QObject* parent = nullptr) : QObject(parent) {}
protected:
    bool eventFilter(QObject* watched, QEvent* event) override
    {
        if (event->type() == QEvent::MouseButtonPress)
        {
            // 处理鼠标按下事件
            // ...
            return true; // 返回 true 表示事件已被过滤
        }
        else if (event->type() == QEvent::KeyPress)
        {
            // 处理键盘按下事件
            // ...
            return true; // 返回 true 表示事件已被过滤
        }
        return QObject::eventFilter(watched, event); // 其他事件传递给目标对象
    }
};
int main(int argc, char* argv[])
{
    QApplication app(argc, argv);
    QWidget widget;
    MyEventFilter filter;
    widget.installEventFilter(&filter);
    widget.show();
    return app.exec();
}
以上示例中,MyEventFilter类是一个事件过滤器,继承自QObject类,并重写了eventFilter函数。在main函数中,创建一个QWidget对象,并将MyEventFilter对象实例filter安装到该对象上,以便拦截和处理鼠标和键盘事件。
【2】QPainter使用简介
QPainter是Qt框架中用于绘图的类,用于在Qt应用程序中进行2D图形渲染。它提供了一套用于绘制图形、绘制文本、设置画刷和画笔等功能的API。
以下是使用QPainter进行绘图的基本步骤:
- 创建一个QPainter对象:在绘图之前,需要创建一个QPainter对象,该对象将用于绘制。
QPainter painter(this); // 在窗口或自定义绘图设备上创建QPainter对象
- 设置绘图参数:可以通过设置画刷(QBrush)和画笔(QPen)来指定绘图的样式和属性。
QBrush brush(Qt::red); // 创建一个画刷对象,设置颜色为红色
QPen pen(Qt::blue);    // 创建一个画笔对象,设置颜色为蓝色
painter.setBrush(brush); // 将画刷对象设置给绘图设备
painter.setPen(pen);     // 将画笔对象设置给绘图设备
- 绘制图形:使用QPainter对象提供的绘图函数绘制所需的图形。
painter.drawRect(20, 20, 100, 100);  // 绘制矩形
painter.drawEllipse(50, 50, 100, 100); // 绘制椭圆
- 绘制文本:使用QPainter对象的绘制文本函数绘制所需的文本。
painter.drawText(20, 150, "Hello Qt!");  // 绘制文本
- 结束绘图:完成绘图后,需要结束绘图操作。
painter.end(); // 结束绘图操作
以上是QPainter的基本使用方法。使用QPainter可以绘制各种图形,以及在窗口或自定义绘图设备上进行自定义绘图。还可以使用QPainter绘制图像、渐变等更高级的绘图操作。
【3】QPainter绘制温度案例
头文件
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QDebug>
#include <QRandomGenerator64>		//生成随机数
#include <QPainter>
// 温度曲线相关的宏
#define PADDING       50
#define INCREMENT     8      // 温度曲线像素增量
#define POINT_RADIUS  3     // 曲线描点的大小
#define TEXT_OFFSET_X 12    // 温度文本相对于点的偏移
#define TEXT_OFFSET_Y 10    // 温度文本相对于点的偏移
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
    Q_OBJECT
public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
    void  paintHigh();
    void  paintLow();
protected:
    bool eventFilter(QObject*watched, QEvent*event) override;
private:
    Ui::Widget *ui;
    // 自定义变量
    int highTemp[7] = {0};
    int lowTemp[7] = {0};
    void updateTemp();
};
#endif // WIDGET_H
源文件
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    updateTemp();
    ui->label_high->installEventFilter(this);
    ui->label_low->installEventFilter(this);
}
Widget::~Widget()
{
    delete ui;
}
void Widget::paintHigh()
{
    QPainter painter(ui->label_high);
    painter.setRenderHint(QPainter::Antialiasing, true); // 抗锯齿
    // 1. 计算 x 轴坐标
        int pointX[7] = {0};
        qDebug()<<"ui->label_high->pos().x() = "<<ui->label_high->pos().x();
        qDebug()<<"ui->label_high->width() = "<<ui->label_high->width();
        for ( int i = 0; i < 7; i++ ) {
            pointX[i] = ui->label_high->pos().x() + PADDING + (ui->label_high->width() - PADDING * 2) / 6 * i;
            qDebug()<<"pointX[" <<i<<"] = "<<pointX[i];
        }
        // 2. 计算 y 轴坐标
            // 2.1 计算平均值
            int tempSum     = 0;
            int tempAverage = 0;
            for ( int i = 0; i < 7; i++ ) {
                tempSum += highTemp[i];
            }
            tempAverage = tempSum / 7;    // 最高温平均值
            qDebug()<<"tempAverage = "<<tempAverage;
            // 2.2 计算 y 轴坐标
            int pointY[7] = {0};
            int yCenter   = ui->label_high->height() / 2;
            int increment = ui->label_high->height() / 20;
            qDebug()<<"ui->label_high->height() = "<<ui->label_high->height();
            qDebug()<<"yCenter = "<<yCenter;
            qDebug()<<"increment = "<<increment;
            for ( int i = 0; i < 7; i++ ) {
                pointY[i] = yCenter - ((highTemp[i] - tempAverage) * increment);
                qDebug()<<"pointY[" <<i<<"] = "<<pointY[i];
            }
            qDebug() <<endl;
            // 3. 开始绘制
            // 3.1 初始化画笔
            QPen pen = painter.pen();
            pen.setWidth(1);                      //设置画笔宽度为1
            pen.setColor(QColor(255, 170, 0));    //设置颜色
            painter.setPen(pen);
            painter.setBrush(QColor(255, 170, 0));    //设置画刷颜色
            painter.setFont(QFont("Microsoft YaHei", 14));
            // 3.2 画点、写文本
            for ( int i = 0; i < 7; i++ ) {
                painter.drawEllipse(QPoint(pointX[i], pointY[i]), POINT_RADIUS, POINT_RADIUS);  // 画点
                painter.drawText(QPoint(pointX[i] - TEXT_OFFSET_X, pointY[i] - TEXT_OFFSET_Y), QString::number(highTemp[i]) + " ℃");    // 画文本
            }
            // 3.3 绘制曲线
            for ( int i = 0; i < 6; i++ ) {  // 循环控制6次
                if ( i == 0 ) {
                    pen.setStyle(Qt::DotLine);     // 虚线
                    painter.setPen(pen);
                } else {
                    pen.setStyle(Qt::SolidLine);    // 实线
                    painter.setPen(pen);
                }
                painter.drawLine(pointX[i], pointY[i], pointX[i + 1], pointY[i + 1]);   // 两点确定一条直线
            }
}
void Widget::paintLow()
{
       QPainter painter(ui->label_low);
        painter.setRenderHint(QPainter::Antialiasing, true);  // 抗锯齿
        // 1. 计算 x 轴坐标
        int pointX[7] = {0};
        for ( int i = 0; i < 7; i++ ) {
            pointX[i] = ui->label_low->pos().x() + PADDING + (ui->label_low->width() - PADDING * 2) / 6 * i;
        }
        // 2. 计算 y 轴坐标
        // 2.1 计算平均值
        int tempSum = 0;
        int tempAverage = 0;
        for ( int i = 0; i < 7; i++ ) {
            tempSum += lowTemp[i];
        }
        tempAverage = tempSum / 7;  // 最高温平均值
        // 2.2 计算 y 轴坐标
        int pointY[7] = {0};
        int yCenter = ui->label_low->height() / 2;
        int increment = ui->label_low->height() / 20;
        for ( int i = 0; i < 7; i++ ) {
            pointY[i] = yCenter - ((lowTemp[i] - tempAverage) * increment);
        }
        // 3. 开始绘制
        // 3.1 初始化画笔
        QPen pen = painter.pen();
        pen.setWidth(1);                    // 设置画笔宽度为1
        pen.setColor(QColor(0, 255, 255));  // 设置颜色
        painter.setPen(pen);
        painter.setBrush(QColor(0, 255, 255));  //设置画刷颜色
        painter.setFont(QFont("Microsoft YaHei", 14));
        // 3.2 画点、写文本
        for ( int i = 0; i < 7; i++ ) {
            painter.drawEllipse(QPoint(pointX[i], pointY[i]), POINT_RADIUS, POINT_RADIUS);
            painter.drawText(QPoint(pointX[i] - TEXT_OFFSET_X, pointY[i] - TEXT_OFFSET_Y), QString::number(lowTemp[i]) + " ℃");
        }
        // 3.3 绘制曲线
        for ( int i = 0; i < 6; i++ ) {
            if ( i == 0 ) {
                pen.setStyle(Qt::DotLine);  //虚线
                painter.setPen(pen);
            } else {
                pen.setStyle(Qt::SolidLine);  // 实线
                painter.setPen(pen);
            }
            painter.drawLine(pointX[i], pointY[i], pointX[i + 1], pointY[i + 1]);
        }
}
bool Widget::eventFilter(QObject *watched, QEvent *event)
{
    if (event->type() == QEvent::Paint) {
        if (watched == ui->label_high) {
            this->paintHigh();
        }
        if (watched == ui->label_low) {
            this->paintLow();
        }
    }
    else if (event->type() == QEvent::MouseButtonDblClick) {
        this->updateTemp();
    }
    return QWidget::eventFilter(watched,event); // 未处理返回false
}
void Widget::updateTemp()
{
    for (int i = 0; i<7;i++) {
        highTemp[i] = 20 + QRandomGenerator::global()->generate() % 10;
        lowTemp[i] = -5 + QRandomGenerator::global()->generate() % 10;
    }
    ui->label_low->update();
    ui->label_high->update();
}
【4】 UI界面设计

【5】温度绘制图
通过双击组件可以更新温度
 
 



















