Qt 事件过滤器使用QPainter绘制温度

news2024/9/25 19:24:04

文章目录

  • 【1】eventFilter使用简介
  • 【2】QPainter使用简介
  • 【3】QPainter绘制温度案例
    • 头文件
    • 源文件
  • 【4】 UI界面设计
  • 【5】温度绘制图


【1】eventFilter使用简介

Qt的eventFilter是一个事件过滤器,可以用来捕获和处理Qt对象的事件。事件过滤器可以被安装到一个对象上,以便在该对象上拦截和处理包含特定类型和内容的事件。下面是eventFilter的简单使用介绍:

  1. 创建一个类,并继承自QObject。这个类将作为事件过滤器的实现。
  2. 在该类中,重写eventFilter函数。eventFilter函数接收两个参数:QObject* watchedQEvent* event,用于捕获事件和处理事件。
    • 参数watched是事件发送方的指针,可以用来检查事件发送方的类型或属性。
    • 参数event是要处理的事件对象,可以用于检查事件类型和内容,并采取相应的处理措施。
  3. 在需要安装事件过滤器的Qt对象上调用installEventFilter函数,将事件过滤器实例添加到该对象。
  4. 在事件过滤器的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进行绘图的基本步骤:

  1. 创建一个QPainter对象:在绘图之前,需要创建一个QPainter对象,该对象将用于绘制。
QPainter painter(this); // 在窗口或自定义绘图设备上创建QPainter对象
  1. 设置绘图参数:可以通过设置画刷(QBrush)和画笔(QPen)来指定绘图的样式和属性。
QBrush brush(Qt::red); // 创建一个画刷对象,设置颜色为红色
QPen pen(Qt::blue);    // 创建一个画笔对象,设置颜色为蓝色

painter.setBrush(brush); // 将画刷对象设置给绘图设备
painter.setPen(pen);     // 将画笔对象设置给绘图设备
  1. 绘制图形:使用QPainter对象提供的绘图函数绘制所需的图形。
painter.drawRect(20, 20, 100, 100);  // 绘制矩形
painter.drawEllipse(50, 50, 100, 100); // 绘制椭圆
  1. 绘制文本:使用QPainter对象的绘制文本函数绘制所需的文本。
painter.drawText(20, 150, "Hello Qt!");  // 绘制文本
  1. 结束绘图:完成绘图后,需要结束绘图操作。
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】温度绘制图

通过双击组件可以更新温度
在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/696236.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【js30天挑战】第四天:数组操作

总结 filter(筛选条件为true的项) map(你想要输出的东西)&#xff0c;进来多少个 出去多少个 sort()&#xff0c;默认可排字母顺序。sort(compareFn(a, b))其中compareFn(a, b)返回的值若大于0则a在b的后面。 reduce()&#xff0c;最复杂。reduce(func(){上一轮计算出的结果…

Vue 3 + vite技术架引入静态文件的问题(require和import方式)

Vue 3 vite技术架无法使用require()的方式引入静态文件 使用Vue 3 vite技术架开发过程中&#xff0c;引入静态资源时&#xff0c;习惯性使用require()引入&#xff0c;突然发现报错了。 研究了一下才发现&#xff0c;好像vite引入静态资源或者插件啥的&#xff0c;不用requi…

JAVA 二维码绘制,可定义背景图与在背景图种的位置,码点绘制避开logo区域10个像素点

效果图&#xff1a; 背景图&#xff1a; 直接看代码和代码说明&#xff1a; 方法drawQr() 为绘制核心&#xff0c;仅绘制出图上的二维码 方法createQr() 包含 读取背景图和 调用drawQr() 。绘制出完整的带有背景图的二维码 drawQr()方法参数说明&#xff1a; * param conten…

新星计划【数据结构与算法】赛道开启,欢迎报名!

前排提醒&#xff1a;这里是新星计划2023【数据结构与算法】学习方向的报名入口&#xff0c;一经报名&#xff0c;不可更换。 ↓↓↓报名方式&#xff1a;新星计划2023【数据结构与算法】学习方向报名入口&#xff01;-CSDN社区 一、关于本学习方向导师 博客昵称&#xff1a;…

上海亚商投顾:沪指探底回升微跌 减速器概念股大涨

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。 市场情绪 指数今日探底回升&#xff0c;三大股指盘中均跌超1%&#xff0c;随后跌幅逐渐收窄&#xff0c;沪指午后一度拉升翻…

Elasticsearch:使用 SIMD 指令加速向量搜索

作者&#xff1a;Chris Hegarty, Elastic Principal Engineer, Lucene PMC 翻译&#xff1a;杰瑞朱 多年来&#xff0c;Java 平台上运行的代码一直受益于自动向量化 —— HotSpot C2 编译器中的 superword 优化&#xff0c;将多个标量操作打包到 SIMD&#xff08;单指令多数据…

CWDM粗波分复用和DWDM密集波分复用的区别?

WDM波分复用技术提供了一种经济高效的解决方案&#xff0c;无需在现有光纤网络中部署额外的光纤即可增加网络容量。 CWDM 和 DWDM 是两种主要的 WDM 技术&#xff0c;具有不同的波长模式、功能、成本和应用。 CWDM 代表粗波分复用&#xff0c;其中“Coarse” 是指通道之间的波…

分享一个内网的屏幕分享软件inletexemc

分享一个内网的屏幕分享软件inletexemc 参考文章&#xff1a;https://zhuanlan.zhihu.com/p/25912687 原本采用的一个叫veyon的电子教室管理软件&#xff0c;虽然可以实现这个效果&#xff0c;但是比较笨重&#xff0c;操作也比较繁琐&#xff0c;具体可参考&#xff1a;http…

对话商越苗峰:未来十年,采购数字化是ERP后最核心应用之一

“从创立开始&#xff0c;商越就非常清楚要做什么、不做什么&#xff0c;这个定位到现在没变&#xff0c;未来也不会变。” 作者|皮爷 出品|产业家 清晰、理智、坚定、条律分明&#xff0c;这是商越创始人苗峰给我的第一感觉。 在见到他之前&#xff0c;我曾想象过这家短短几…

来酷智生活,Type-C十二合一扩展坞来了

联想最新推出的“来酷智生活Type-C十二合一扩展坞”为用户带来更多接口选择&#xff0c;方便实用。 这款扩展坞包含12个接口&#xff0c;包括2个USB 3.2&#xff0c;2个USB 2.&#xff0c;2个HDMI接口&#xff0c;TF卡插槽&#xff0c;SD卡插槽&#xff0c;DP接口&#xff0c;P…

电压放大器在超声波检测中的应用

电压放大器是一种用于放大电压信号的电子设备&#xff0c;它具有低噪声、高增益、线性度高等特点&#xff0c;被广泛应用于各种电子设备中。在超声波检测中&#xff0c;电压放大器在信号的采集和处理中发挥着非常重要的作用。 超声波检测是一种通过声波的反射和传播来检测物体内…

系统定制开发-安卓输入法将应用顶起问题

输入法弹出会导致应用窗口往上移动 InputMethodService.java中有关窗口重置代码 只需要重写onComputeInsets,将outInsets.contentTopInsets 设为decor.getHeight() Overridepublic void onComputeInsets(final InputMethodService.Insets outInsets) {super.onComputeInsets(o…

6.2 文件与目录管理

6.2.1 文件与目录的检视&#xff1a; ls 在Linux中&#xff0c;ls指令最常被执行&#xff0c;因为我们随时都要知道文件或者目录的相关信息。Linux的文件记录信息很多&#xff0c;因此ls没有需要全部都列出来。所以下达ls时&#xff0c;默认的有&#xff1a;非隐藏文件的文件名…

电脑开机太慢!怎么让电脑开机速度变快?

电脑刚买来的时候&#xff0c;开机速度很快&#xff0c;用了一段时间后&#xff0c;开机速度越来越慢&#xff0c;甚至要等上好几分钟&#xff0c;这实在是太让人苦恼了!电脑开机太慢&#xff0c;怎么让电脑开机速度变快&#xff1f;其实想要解决这个问题很简单&#xff0c;我们…

centos安装docker后,ping不能服务器ip

工作中碰的问题&#xff0c;记录下解决过程&#xff1a; 问题描述 2台内网服务器&#xff1a;A&#xff08;172.20.72.77&#xff09;和B&#xff08;172.17.3.222&#xff09;&#xff0c;在A服务上ping B 。 安装 docker之前是可以ping通&#xff0c;安装docker之后确ping不…

周鸿祎考上了清华博士

我是卢松松&#xff0c;点点上面的头像&#xff0c;欢迎关注我哦&#xff01; 绝大多数人在功成名就后&#xff0c;想做的事&#xff1a;盖一所希望小学、去学校当老师或者当学生。而周鸿祎选择了去清华读博士。 360的老板周鸿祎&#xff0c;在他53岁的时候考上了清华博士&…

【虚拟机】电脑里面VirtualBox虚拟机不见了

非常突然&#xff0c;打开VirtualBox时&#xff0c;发现工具栏里面之前创建的虚拟机都不见了&#xff0c;自己又没有删&#xff0c;咋回事呢&#xff0c;有些慌&#xff0c;之前的撸力全没有了&#x1f47f;。。。之前有关注过存储文件路径&#xff0c;去找了一下发现*.vdi和*.…

多模态超省钱!JinaChat 面向开发者的大模型服务

2023年6月25日 Jina AI 发布了 JinaChat&#xff0c;一个面向开发者和终端用户的多模态大模型API。传统大型语言模型往往将竞争力建立在「参数多」和「刷分强」的基础上&#xff0c;然而对于应用开发者来说&#xff0c;传统模型商的 API 并不能很好地让开发者低成本的实现解决方…

记录spring boot引入JWT遇到的问题---突然自己展现登录页面

才用了两天的swagger&#xff0c;本来一切如常&#xff0c;焦头烂额写个带token的登录&#xff0c;终于写好了&#xff0c;准备验证一把&#xff0c;就发现swagger莫名其妙自己出现登录界面了&#xff0c;也不知道账号密码&#xff0c;慌得一批 1. 现象说明 试了自己写的登录账…

centos7下部署python

1.在liunx上安装python运行环境 [rootlocalhost ~]# yum -y install gcc[rootlocalhost ~]# yum -y install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gdbm-devel db4-devel libpcap-devel xz-devel libffi-devel2.进入到安…