【Qt绘制仪表盘】

news2024/11/19 22:46:30

目的

使用Qt的绘制事件绘制一个仪表盘

思路

  1. 需要创建一个带绘制事件的控件
  2. 重写绘制事件
  3. 显示

实现

以下是实现代码,可复制到程序到,直接运行。

.h
// GaugeWidget.h
#ifndef GAUGEWIDGET_H
#define GAUGEWIDGET_H

#include <QWidget>

class GaugeWidget : public QWidget
{
    Q_OBJECT
public:
    explicit GaugeWidget(QWidget *parent = nullptr);

    void setValue(qreal value){m_value = value;}

protected:
    void paintEvent(QPaintEvent *event) override;

private:
    qreal m_value;
};

#endif // GAUGEWIDGET_H

.h分析
  • 继承QWidget类,重新实现void paintEvent(QPaintEvent *event) override;事件;
  • 设置仪表盘当前的数据void setValue(qreal value){m_value = value;}
.cpp
// GaugeWidget.cpp
#include "GaugeWidget.h"
#include <QPainter>

#include <QDebug>
GaugeWidget::GaugeWidget(QWidget *parent) : QWidget(parent), m_value(0)
{

}

void GaugeWidget::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event);

    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);

    qDebug().noquote() << "[" << __FILE__ << __LINE__ << "]" << this->size();
    // 绘制表盘
    painter.save();
    painter.translate(width()/2, height()/2);
    painter.setPen(Qt::NoPen);
    painter.setBrush(QBrush(QColor(255, 255, 255)));
    painter.drawEllipse(-100, -100, 200, 200);
    painter.setBrush(QBrush(QColor(200, 200, 200)));
    painter.drawEllipse(-95, -95, 190, 190);

    static const int majorTickCount = 12;
    static const int minorTickCount = 5;

    QFont font;
    font.setPointSize(8);
    painter.setFont(font);

    painter.save();
    for (int i = 0; i <= majorTickCount; i++) {
        qreal angle = i * 360.0 / majorTickCount;
        painter.rotate(angle);

        // 绘制刻度线
        if (i < majorTickCount) {
            painter.setPen(QPen(QColor(255, 255, 255), 2));
            painter.drawLine(0, -85, 0, -95);
        }

        // 绘制刻度值
        if (i % 2 == 0) {
            painter.setPen(QPen(QColor(255, 0, 0)));
            qreal value = i * 360.0 / majorTickCount;
            QString text = QString::number(value, 'f', 0);
            QRectF textRect(-50, -100, 100, 100);
            painter.drawText(textRect, Qt::AlignTop|Qt::AlignHCenter, text);
        }

        painter.rotate(-angle);
    }

    for (int i = 0; i < majorTickCount; i++) {
        for (int j = 1; j <= minorTickCount; j++) {
            qreal angle = (i + j / (qreal)minorTickCount) * 360.0 / majorTickCount;
            painter.save();
            painter.rotate(angle);

            painter.setPen(QPen(QColor(255, 255, 255), 1));
            painter.drawLine(0, -90, 0, -95);

            painter.restore();
        }
    }
    painter.restore();

    // 绘制指针
    qreal angle = (m_value / 60.0+0.5) * 360;
    painter.rotate(angle);
    painter.setPen(QPen(QColor(255, 0, 0), 3));
    painter.drawLine(0, 0, 0, 60);
    painter.restore();
}
.cpp分析

paintEvent函数是继承自QWidget的paintEvent事件处理函数,用于绘制小部件的界面。paintEvent函数首先创建一个QPainter对象,然后设置抗锯齿渲染。其余部分主要是绘制仪表盘和指针。具体绘制过程如下:

  1. 绘制表盘:
  • 将绘图原点平移到小部件的中心。

  • 绘制外圆和内圆,用QBrush用来填充圆形。

  • 根据majorTickCount(12)的值循环绘制刻度线和刻度值。每次循环需要计算出角度,然后将绘图原点旋转该角度。

  • 如果当前是大刻度线,则用QPen绘制白色线条。

  • 如果当前是大刻度线的偶数,则用QPen绘制红色刻度值,绘制完成后将绘图原点旋转回来。

  • 根据majorTickCount(12)和minorTickCount(5)的值循环绘制小刻度线。每次循环需要计算出角度,然后将绘图原点旋转该角度,绘制小刻度线,然后将绘图原点旋转回来。

  1. 绘制指针:
  • 根据m_value的值计算出指针应该指向的角度,并将绘图原点旋转该角度。
  • 用QPen绘制红色的指针线。
  • 将绘图原点旋转回来。
在MainWindow中使用自定义控件类GaugeWidget,测试表盘绘制效果:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "GaugeWidget.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    GaugeWidget *gaugeWidget = new GaugeWidget;
    setCentralWidget(gaugeWidget);
    gaugeWidget->setValue(40);
}

MainWindow::~MainWindow()
{
    delete ui;
}

编译运行程序,效果如下:

在这里插入图片描述

结论

繁华到极致,腐朽到荒凉

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

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

相关文章

redis事务及管道

目录 redis事务 1、redis事务命令 2、示例 redis管道 1、管道命令 2、示例 redis事务 在Redis中&#xff0c;事务是一组命令的有序队列&#xff0c;可以一次执行多个命令&#xff0c;本质是一组命令的集合。一个事务中的所有命令都会序列化&#xff0c;按顺序地串行化执…

【JavaEE】多线程 (1)

目录 1. 认识线程&#xff08;Thread&#xff09; 1) 线程是什么 2) 为啥要有线程 3) 进程和线程的区别 2.第⼀个多线程程序 3.多线程的其他创建方式 方法二:实现 Runnable 接⼝ 方法三:匿名内部类 方法四:实现Runable, 重写run, 匿名内部类 方法五:使用lambda表达式…

Leetcode—35.搜索插入位置【简单】

2023每日刷题&#xff08;四十&#xff09; Leetcode—35.搜索插入位置 实现代码 int lower_bound(int* arr, int numsSize, int tar) {int left 0, right numsSize;int mid;// 左闭右开[left, right)while(left < right) {mid left (right - left) / 2;if(arr[mid] &…

4G执法记录仪在大型安保集团,保安集团、蓝天救援队中的 应用,行为规范化,人员定位,考勤打卡,应急指挥调度

【智能化升级】揭秘4G/5G执法记录仪在安保与救援领域如何重塑行业标准与效率 在快速发展的社会当中&#xff0c;大型安保集团、保安集团和蓝天救援队所肩负的任务日益繁重与复杂。无论是在平时的治安巡查、安保执勤&#xff0c;还是在突发公共事件的应急响应中&#xff0c;如何…

C++ STL-----容器

STL容器就是将运用最广泛的一些数据结构实现出来 常用的数据结构&#xff1a;数组, 链表,树, 栈, 队列, 集合, 映射表 等 这些容器分为序列式容器和关联式容器两种: 序列式容器:强调值的排序&#xff0c;序列式容器中的每个元素均有固定的位置。 关联式容器:二叉树结构&…

JavaScript解构数组

还记得之前我们是如何读取到数组里面的元素的么&#xff1f; const arr [2, 3, 4]; const a arr[0]; const b arr[1]; const c arr[2];然后通过这个方式去读取数组中的数据&#xff1b; 现在我们可以使用解构赋值的方法去实现 const [x, y, z] arr; console.log(x, y, …

网络运维与网络安全 学习笔记2023.11.25

网络运维与网络安全 学习笔记 第二十六天 今日目标 ACL原理与类型、基本ACL配置、高级ACL配置 高级ACL之ICMP、高级ACL之telnet ACL原理与类型 项目背景 为了企业的业务安全&#xff0c;要求不同部门对服务器有不同的权限 PC1不能访问Server PC2允许访问Server 允许其他所…

Linux基本指令(前篇)

目录 1.ls指令 2.pwd指令 3.cd 指令 4.touch指令 5.mkdir指令&#xff08;重要&#xff09; 6.rmdir指令 && rm 指令&#xff08;重要&#xff09; 7.man指令&#xff08;重要&#xff09; 1.ls指令 ls 选项 目录或文件 对于目录&#xff0c;该命令列出该目录下的所…

MYSQL基础知识之【添加数据,查询数据】

文章目录 前言MySQL 插入数据通过命令提示窗口插入数据使用PHP脚本插入数据 MySQL 查询数据通过命令提示符获取数据使用PHP脚本来获取数据内存释放 后言 前言 hello world欢迎来到前端的新世界 &#x1f61c;当前文章系列专栏&#xff1a;Mysql &#x1f431;‍&#x1f453;博…

STM32 配置中断常用库函数

单片机学习 目录 一、配置AFIO相关库函数 1.1函数GPIO_AFIODeInit 1.2函数GPIO_EventOutputConfig 1.3函数GPIO_EventOutputCmd 1.4函数GPIO_EXTILineConfig 二、配置EXTI相关库函数 2.1函数EXTI_DeInit 2.2函数EXTI_Init 2.3函数EXTI_StructInit 2.4函数 EXTI_Gener…

html实现我的故乡,城市介绍网站(附源码)

文章目录 1. 我生活的城市北京&#xff08;网站&#xff09;1.1 首页1.2 关于北京1.3 北京文化1.4 加入北京1.5 北京景点1.6 北京美食1.7 联系我们 2.效果和源码2.1 动态效果2.2 源代码 源码下载 作者&#xff1a;xcLeigh 文章地址&#xff1a;https://blog.csdn.net/weixin_43…

spring本地事务与单/多线程

请直接看原文 原文链接:多线程与数据库事务以及数据库连接之间的关系 - 知乎 (zhihu.com) -------------------------------------------------------------------------------------------------------------------------------- 今天我们来梳理一下&#xff0c; 多线程、数…

033.Python面向对象_类补充_生命周期

我 的 个 人 主 页&#xff1a;&#x1f449;&#x1f449; 失心疯的个人主页 &#x1f448;&#x1f448; 入 门 教 程 推 荐 &#xff1a;&#x1f449;&#x1f449; Python零基础入门教程合集 &#x1f448;&#x1f448; 虚 拟 环 境 搭 建 &#xff1a;&#x1f449;&…

Java基准测试工具JMH的简介与使用

JMH是一套Java基准测试工具&#xff0c;用于对Java执行进行基准测试以及生成测试报告。平时应用于Java一些基础Api或者一些工具类这种离开网络因素的纯系统测试。 使用方式 maven引入&#xff1a; <dependency><groupId>org.openjdk.jmh</groupId><art…

linux账户管理实例二

要求&#xff1a;我的 用户pro1&#xff0c;pro2&#xff0c;pro3是同一个项目开发人员&#xff0c;想让这三个人用户在同一个目录下工作&#xff0c;但这三个人拥有自己的主文件夹和基本的私有用户组&#xff0c;工作目录为/srv/projecta&#xff0c;如何实现&#xff1f; 分…

03_MySQL基本SQL语句讲解

#课程目标 能够创建、删除数据表能够对表里的数据记录进行增加、删除、修改、查询操作能够创建、删除用户能够给用户授权并回收权限了解delete和truncate语句的区别 #一、数据库基本操作 ##1、查看数据库相关信息 mysql> show databases; 查看所有数据库 mysql>…

【机器学习】聚类(三):原型聚类:高斯混合聚类

文章目录 一、实验介绍1. 算法流程2. 算法解释3. 算法特点4. 应用场景5. 注意事项 二、实验环境1. 配置虚拟环境2. 库版本介绍 三、实验内容0. 导入必要的库1. 全局调试变量2. 调试函数3. 高斯密度函数&#xff08;phi&#xff09;4. E步&#xff08;getExpectation&#xff09…

【开源组件】- 关于Jetcache的使用

关于Jetcache的使用 &#x1f604;生命不息&#xff0c;写作不止 &#x1f525; 继续踏上学习之路&#xff0c;学之分享笔记 &#x1f44a; 总有一天我也能像各位大佬一样 &#x1f31d;分享学习心得&#xff0c;欢迎指正&#xff0c;大家一起学习成长&#xff01; JetCache是由…

MobileNets发展与总结

写在前面&#xff1a;本博客仅作记录学习之用&#xff0c;部分图片来自网络&#xff0c;如需引用请注明出处&#xff0c;同时如有侵犯您的权益&#xff0c;请联系删除&#xff01; 文章目录 引言MobileNetsMobileNet - V1思想代码实现 MobileNet - V2思想代码实现 MobileNet - …

LeetCode Hot100 105.从前序与中序遍历序列构造二叉树

题目&#xff1a;给定两个整数数组 preorder 和 inorder &#xff0c;其中 preorder 是二叉树的先序遍历&#xff0c; inorder 是同一棵树的中序遍历&#xff0c;请构造二叉树并返回其根节点。 代码&#xff1a; class Solution {private Map<Integer, Integer> indexM…