【Qt绘制仪表盘】

目的

使用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.hqwc.cn/news/217850.html

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

相关文章

Halcon [fill_up_shape],[close_circle],[dilation_circle]和[shape_trans]图像处理时填充区别

文章目录 文章专栏前言两者的区别fill_up_shapeshape_transclose_circledilation_circle 总结 文章专栏 我的Halcon开发 CSDN专栏 前言 本文用的案例是&#xff1a;Example: %HALCONEXAMPLES%/hdevelop/Applications/Completeness-Check/ball.hdev 两者的区别 [shape_trans]是…

【微服务专题】SpringBoot自动配置简单源码解析

目录 前言阅读对象阅读导航前置知识什么是自动配置0.1 基本概念0.2 SpringBoot中的【约定大于配置】0.3 从SpringMVC看【约定大于配置】0.4 从Redis看【约定大于配置】0.5 小结 笔记正文一、EnableAutoConfiguration源码解析二、SpringBoot常用条件注解源码解析2.1 自定义条件注…

【手写实现一个简单版的Dubbo,深刻理解RPC框架的底层实现原理】

手写实现一个简单版的Dubbo&#xff0c;深刻理解RPC框架的底层实现原理 RPC框架简介了解Dubbo的实现原理服务暴露服务引入服务调用 手写实现一个简单版的Dubbo服务暴露ServiceBeanProxyFactory#getInvokerProtocol#exportRegistryProtocol#export 服务引入RegistryProto#referD…

带你用uniapp从零开发一个仿小米商场_2.创建空白项目及公共样式引入

创建空白项目 打开uniapp 点击新建->项目 如下, 是编辑你项目的名字的地方是你项目存放地址,可以点击浏览器去文件管理里面选地址是模板选择,这里选择默认模板就好是一些其他选择比如uvue能让你项目在编译成软件时运行更快,unicloud能让你用js写后端,且直接就是云开发,g…

1.6 C语言之数组概述

1.6 C语言之数组概述 一、数组二、练习 一、数组 所谓数组&#xff0c;就是内存中一片连续的空间&#xff0c;可以用来存储一组同类型的数据 数组有下标&#xff0c;从0开始&#xff0c;可以理解为是给数组中的元素编号&#xff0c;便于后续寻址访问 我们来编写一个程序&…

zerotier 搭建 moon中转服务器 及 自建planet

搭建moon 服务器 环境准备 # 安装依赖 yum install wget gcc gcc-c git -y yum install json-devel -y# 下载及安装 curl -s https://install.zerotier.com/ | sudo bash节点ID 配置 配置moon.json文件 cd /var/lib/zerotier-one/# 导出依赖 zerotier-idtool initmoon ide…

本地事务和分布式事务

请直接看原文 原文链接:彻底搞清楚什么是分布式事务 - 知乎 (zhihu.com) -------------------------------------------------------------------------------------------------------------------------------- 1、什么是本地事务 多个sql操作,被同一个线程执行, 使用…

【WSA】无法打开 适用于 Android™ 的 Windows 子系统,因为它处于脱机状态。可能缺少存储设备,或者存储设备已断开连接。

问题描述 之前可以正常使用适用于 Android™ 的 Windows 子系统&#xff08;WSA&#xff09;&#xff0c;但突然间无法启动了。 当尝试启动WSA中的软件时&#xff0c;都会出现以下错误提示&#xff1a; 无法打开 适用于 Android™ 的 Windows 子系统&#xff0c;因为它处于脱…

python安装redis库

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…

浅析基于物联网的远程抄表系统的设计及应用

安科瑞 华楠 摘 要&#xff1a;本文基于物联网的概念&#xff0c;使用 ZigBee、通用分组无线服务技术两种无线通信技术相结合的方式实现远程抄表并对数据进行存储和管理。此系统设计主要分为硬件方面的设计和软件方面的设计&#xff0c;硬件方面的设计需要完成三个部分的硬件制…

基于51单片机超市快递寄存自动柜设计源程序

一、系统方案 1、本设计采用这51单片机作为主控器。 2、存包&#xff0c;GSM短信取件码。 3、液晶1620显示。 4、矩阵键盘输入取件码&#xff0c;完成取包。 二、硬件设计 原理图如下&#xff1a; 三、单片机软件设计 1、首先是系统初始化 /******************************…

postman和Jmeter做接口测试的区别(经验之谈)

接口测试的目的 API 测试作为集成测试的一部分&#xff0c;经过被测应用的接口&#xff08;API&#xff09;来确定是否在功能、可靠性、性能和安全方面达到预期的软件测试。因为 API 都没有 GUI 界面&#xff0c;API 测试都是在通信层进行的。 1.建立接口用例集 Postman功能…