当前位置:网站首页>Qt | 实现一个简单的可以转动的仪表盘
Qt | 实现一个简单的可以转动的仪表盘
2022-08-02 14:12:00 【华为云】
环境: vs2017+Qt5.14.2
效果图:
准备工作:
效果图中的可以转动的仪表盘效果分为三个部分:
背景图(就是带去掉中间白色原点,去掉中间蓝色指针省下的部分);
指针图片(中间蓝色的指针部分,不包括指针上的白色圆点);
原点图片(中间白色的圆点)
原理:
在 paintEvent()中绘制这三张图片。当需要旋转指针的角度时,改变指针图片的角度,再调用 update()函数重新绘制显示就可以了。
具体实现:
1.定义旋转角度成员变量:int m_nValue;//指针旋转角度。
2.重载 paintEvent()函数。
3.加载三张图片。
QPixmap img = QPixmap(":/image/banhuan.png");
QPixmap needle = QPixmap(":/image/zhizhen.png");
QPixmap overlay = QPixmap(":/image/zhizhenyuan.png");
4.在 paintEvent()函数中进行绘制。
void CDialBox::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
painter.save();//保存painter.setRenderHint(QPainter::SmoothPixmapTransform, true); //平滑像素图,防止图形走样painter.translate(this->width() / 2, this->height() / 2); // 原点定位在中间位置// 背景图painter.drawPixmap(-img->width() / 2, -img->height() / 2, img); // 指针图painter.rotate(m_nValue);//设置旋转角度painter.drawPixmap(-needle.width() / 2, -needle.height() + needle.width() / 2, needle); //原点图painter.drawPixmap(-overlay.width() / 2, -overlay.height() / 2, overlay);painter.restore();//恢复
}
其中:painter.save();painter.restore();为保存 QPainter 当前的状态和恢复 QPainter 当前的状态。这里使用这两个函数主要是服务于 painter.translate()函数的。
因为 painter.translate(x, y)函数用来设置当前 QPainter 的相对坐标。正常 QPainter 的坐标原点(0,0)在屏幕的左上角,调用 painter.translate(x, y)函数,会将原点设置为指定的(x,y)的位置,也就是说屏幕的(x,y)为 QPainter 画布的(0,0)位置。
为了防止画布上的图片有缩放或拉伸导致的图像走形,可以调用 painter.setRenderHint(QPainter::SmoothPixmapTransform, true);来进行平滑设置。
在绘制图形时顺序很重要,先调用 painter.drawPixmap()函数进行绘制的图形在最下面,后面调用的会覆盖在之前的图形之上,所以根据效果图,应该先绘制背景图片,再绘制指针图片,最后绘制原点图片。
因为此时原点(0,0)的位置在效果图的最中间位置,所以绘制背景图时的(x,y)应该为(-img->width() / 2, -img->height() / 2);
指针图的 X 值为负的宽度的一半,Y 值为负的高度的值加上宽度的一半。调用 painter.rotate()函数是用来将画布以坐标原点为中心进行顺时针旋转指定的角度。所以定义一个成员变量来给这个角度进行传值。
原点图的(x,y)应该为(-overlay.width() / 2, -overlay.height() / 2);
5.改变指针角度
定义一个改变指针角度值的函数 void valueChanged(int value);
void CDialBox::valueChanged(int value)
{
m_nValue = value;
update();
}
设置角度的值,调用 update()函数进行刷新。调用 update();函数会执行 paintEvent();
边栏推荐
- KiCad常用快捷键
- How to simulate 1/3 probability with coins, and arbitrary probability?
- Yolov5 official code reading - prior to transmission
- Golang 垃圾回收机制详解
- MATLAB绘制平面填充图入门详解
- 6.统一记录日志
- 永久更改pip源
- 第二十五章:一文掌握while循环
- 利用plot_surface命令绘制复杂曲面入门详解
- Introduction to in-order traversal (non-recursive, recursive) after binary tree traversal
猜你喜欢
Detailed introduction to the hierarchical method of binary tree creation
Codeforces Round #605 (Div. 3)
Configure clangd for vscode
剑指offer:反转链表
Open the door to electricity "Circuit" (3): Talk about different resistance and conductance
MATLAB绘制平面填充图入门详解
Mysql之MVCC
6. Unified logging
[System Design and Implementation] Flink-based distracted driving prediction and data analysis system
第三十一章:二叉树的概念与性质
随机推荐
Open the door of power and electricity "Circuit" (2): Power Calculation and Judgment
What are IPV4 and IPV6?
Mysql的锁
KiCad Common Shortcuts
软件测试基础知识(背)
The SSE instructions into ARM NEON
企业的电子签名、私钥签名
Win11 keeps popping up User Account Control how to fix it
【离散化+前缀和】Acwing802. 区间和
Unity Line-Renderer
[STM32 Learning 1] Basic knowledge and concepts are clear
Configure clangd for vscode
学习笔记(01):activiti6.0从入门到精通-工作流的介绍以及插件的安装
二叉排序树与 set、map
STM32LL library use - SPI communication
UnityAPI-Ray-Physics
Mysql lock
Codeforces Round #624 (Div. 3)
模板系列-并查集
第二十五章:一文掌握while循环