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

文章目录

  • 【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_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic: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);                      //设置画笔宽度为1pen.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);                    // 设置画笔宽度为1pen.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.hqwc.cn/news/6089.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于SpringBoot和Vue的医疗设备管理系统的设计与实现(源码+文档+报告)

伴随着网络技术的发展&#xff0c;网络巨头们也在各自的行业中展开了激烈的竞争。网络技术已经渗透到了社会的各个角落&#xff0c;移动支付、远程医疗和健康管理等多种网络技术的普及也日益广泛。同时&#xff0c;网络产业的崛起也极大地影响了传统产业。对医疗设备管理系统的…

Ubuntu 20.04 LTS x86_64 SPEC CPU 2006 cpu2006-1.2.iso 测试笔记

环境 安装依赖项 sudo apt install gfortran 挂载iso sudo mkdir /mnt/cpu2006 sudo mount cpu2006-1.2.iso /mnt/cpu2006 安装 cd /mnt/cpu2006 sh install.sh -d /home/speccpu/cpu2006 SPEC CPU2006 InstallationTop of the CPU2006 tree is /mnt/cpu2006Installing F…

分析Spring Boot项目启动慢原因之 《一》打印bean耗时

分析Spring Boot项目启动原因之 一 打印bean耗时 由于项目比较久远&#xff0c;积累的代码犹如屎山&#xff0c;然后项目启动也特别慢&#xff0c;然后产生想要优化一下启动速度&#xff0c;故写了一个Bean启动时的耗时分析&#xff1a;package com.tekrally.assetManagement.u…

Mysql数据库管理

Mysql数据库管理 一、Mysql数据库管理1.常用的数据类型&#xff1a;2.查看数据库结构1.查看当前服务器中的数据库2.查看数据库中包含的表3.查看表的结构&#xff08;字段&#xff09; 二、SQL语句1.创建和删除数据库和表1.创建新的数据库2.创建新的表 2.管理表中的数据记录1.向…

LabVIEW开发呼吸分析系统

LabVIEW开发呼吸分析系统 在日常生活中&#xff0c;许多人都在练习调息法&#xff0c;但大多数人都不知道如何以完美的方式做。不当的做法不会带来适当的结果。一种使用LabVIEW分析呼吸信号的方法&#xff0c;以使人们以完美的方式练习调息。这有助于从业者按照系统指定的说明…

规划电子类专业生涯:打造单片机/嵌入式技术专家之路

如果我是一个电子类专业的学生&#xff0c;打算将来从事单片机/嵌入式方向的职业&#xff0c;我可能会采取以下步骤来规划我的职业生涯&#xff1a; 学术准备&#xff1a;我将全面学习电子工程的基础知识&#xff0c;包括模拟电子、数字电子、信号处理等方面的知识。我会确保自…

C++课程学习记录

目录 1. 前置说明2. 二叉树的模拟2.1 参考资料2.2 二叉树的构建2.2.1 递归构建2.2.2 迭代构建 2.3 二叉树的遍历2.4 二叉树的应用 3. 继承与派生3.1 最简单的生死3.2 动态申请空间的生死3.3 继承中的protectd权限3.4 三种继承方式3.5 修改某些继承成员的继承类型3.6 多级派生3.…

前端搭建名言生成器(内含源码)

目录 前言 名言生成器 页面搭建 功能实现 前言 今天呢我们来给大家展示的&#xff0c;就是一个非常非常简单的名言生成器&#xff0c; 那么它的功能的非常简单&#xff0c;就是我们通过点击按钮&#xff0c;然后可以生成名人名言&#xff0c;然后我们也可以点击按钮将它分享到…

力扣算法刷题Day54|休息日总结:动态规划之股票问题

股票问题 〉题型分类 股票问题 〉解题思路 〉方法论 确定dp数组&#xff08;dp table&#xff09;以及下标的含义 枚举股票买入/持有/卖出/不持有/冷冻期等所有可能状态分析哪些状态能合并&#xff0c;哪些需要分开考虑定义二维数组dp[i][j]&#xff0c;其中i表示第i天&#x…

C++ Primer(读书笔记)

C源文件通常以.cc、.cxx、.cpp、.cp、.C作为后缀来命名 C语言未定义输入输出语句&#xff0c;而是提供了一个全面的标准库来提供IO机制&#xff0c;对应 iostream、fstream、sstream std::cout<<"Enter Two Numbers"<<std::endl;&#xff0c;这条语句执…

HoloLens2与Unity的Socket通信踩坑日记

最近想让Hololens中获取电脑中更新的数据&#xff0c;打算使用套接字的方式进行通信&#xff0c;明明在unity中模拟测试可以进行正常通信&#xff0c;但是将软件部署到HoloLens上通信总是失败&#xff0c;找了很久的原因&#xff0c;找了很久的原因&#xff0c;终于能够正常通信…

C/C++内存管理(内存分布、动态内存分配、动态内存分配与释放、内存泄漏等)

喵~ 内存之5大区&#xff08;栈区、堆区、静态区、常量区、代码区&#xff09;C/C中各自的内存分配操作符内存泄露?内存泄漏检测方法 内存之5大区&#xff08;栈区、堆区、静态区、常量区、代码区&#xff09; 1、栈区&#xff08;stack&#xff09;&#xff1a;由编译器自动分…