Qt自定义控件--仪表盘

一、前言

本篇博客是学习的大佬feiyangqingyun的博客,博客链接,有兴趣的可以去看一下。通过本次学习,让我对Qt的绘图技巧有了很大的提升,万分感谢大佬:飞扬青云

二、效果展示

在这里插入图片描述

三、绘图过程详解

我把仪表盘划分为五个部分,分别表盘框架刻度线刻度值数值指针,下面开始分步讲解。

2.1、表盘框架

在这里插入图片描述
表盘框架分为六部分:表盘框架外圆、表盘框架中间圆、表盘框架彩环、表盘框架内圆和中心红圆环和中心圆,具体怎么绘制在此不做过多赘述,不懂就去研究一下Qt的绘图原理。
值得注意的技巧:

坐标系平移painter->translate(width()/2,height()/2)
等比例缩放painter->scale(side / 200.0, side / 200.0)

2.2、刻度线

在这里插入图片描述
刻度绘制有个很骚的操作,旋转坐标系painter.rotate(Angle),Qt的坐标系是x轴正方向向右,y轴正方向向下,例如我要从左开始绘制刻度线,直接将坐标系旋转135°,然后每画一个刻度旋转一个刻度对应的角度间隔(270°/(100-0))。

2.3、刻度值

在这里插入图片描述
绘制刻度值不采用旋转坐标的方法,采用极坐标计算坐标。初始坐标系为水平向右为x轴正方向,垂直向下为y轴正方向,现在要从0开始绘制,极坐标是逆时针为正反向,所以0处的弧度为(360°-135°) * (180 / PI),刻度跨度总共是270°,所以每个大刻度值之间的角度间隔是270°/10,相应地也转化为弧度制。然后使用三角公式x=r * cosa,y=r * sina,cosa和sina是值对应的角度的弧度制。但是这样还不够,因为绘制文字是在一个矩形框里面绘制,如果我们按算出来的x和y进行绘制,那这个x和y对应矩形框的左上角坐标,所以绘制出来的效果会对不齐。为了解决这个问题,首先我们需要修改字体的像素值,然后计算出值(对应的矩形框)的宽度和高度,然后在实际绘制时,对计算出的x和y做一个偏移处理(例如,宽、高的一半),这样画出来的刻度效果会好很多。

2.3、数值

在这里插入图片描述
数值直接绘制在中心即可。

2.4、指针

在这里插入图片描述
指针是由一个细长的等边三角形组成的,绘制指针依然采用旋转坐标系的方法绘制。从0开始绘制,首先旋转45°,取三个点(-5,0)、(5,0)、(0,radius),也就是在x轴左右取一对对称点,在y轴上取一个点,然后根据当前值计算旋转坐标系的角度,指针就会随之移动。具体绘制时,可将三个点放在一个集合里,然后进行绘制即可。

四、锦上添花

在这里插入图片描述
这一步是给仪表盘加一个反光的效果,产生一种真实感。原理是用一个小圆去减掉大圆,然后用渐变画刷绘制。

旋转仪表盘是一种常见的显示控件,可以用来展示一些数据,如速度、油量、温度等,下面我将介绍如何使用Qt编写一个旋转仪表盘控件。 首先,我们需要在Qt中创建一个新的自定义控件类。可以通过Qt Creator中的“添加新文件”功能来创建一个QWidget派生类。在这个类中,我们需要实现paintEvent()函数来绘制仪表盘。 在paintEvent()函数中,我们可以使用QPainter来绘制仪表盘的各个部分,包括刻度线、指针、文字等。具体实现可以参考以下代码: ```C++ void RotatingDial::paintEvent(QPaintEvent *event) { // 设置背景色 QPalette pal(palette()); pal.setColor(QPalette::Background, Qt::white); setAutoFillBackground(true); setPalette(pal); // 绘制刻度线 QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing, true); painter.translate(width() / 2, height() / 2); painter.setPen(QPen(Qt::black, 2)); for (int i = 0; i < 60; i++) { painter.drawLine(0, -100, 0, -90); painter.rotate(6); } // 绘制指针 painter.save(); painter.rotate(m_angle); painter.setBrush(Qt::red); painter.setPen(Qt::NoPen); painter.drawConvexPolygon(m_pointer, 3); painter.restore(); // 绘制文字 QFont font("Arial", 12, QFont::Bold); painter.setFont(font); painter.drawText(-30, 50, "Speed"); } ``` 在上面的代码中,我们首先设置了控件的背景色为白色。然后使用QPainter绘制了60条刻度线,并旋转6度。接着,我们绘制了一个红色的指针,并根据m_angle属性来旋转指针的角度。最后,我们使用QPainter绘制了文字“Speed”。 在我们的自定义控件中,我们需要一个属性来控制指针的角度。我们可以使用Q_PROPERTY宏来定义这个属性,例如: ```C++ class RotatingDial : public QWidget { Q_OBJECT Q_PROPERTY(int angle READ angle WRITE setAngle) public: RotatingDial(QWidget *parent = nullptr); int angle() const; void setAngle(int angle); private: int m_angle; QPolygon m_pointer; }; ``` 在上面的代码中,我们使用Q_PROPERTY宏定义了angle属性,并提供了getter和setter函数。我们还定义了一个私有变量m_angle来存储当前的角度,以及一个QPolygon对象m_pointer来存储指针的形状。 在setAngle()函数中,我们设置m_angle属性,并根据新的角度计算指针的位置: ```C++ void RotatingDial::setAngle(int angle) { if (angle != m_angle) { m_angle = angle; m_pointer.setPoint(0, QPoint(0, -90)); m_pointer.setPoint(1, QPoint(5, 0)); m_pointer.setPoint(2, QPoint(-5, 0)); m_pointer.translate(0, 100); update(); } } ``` 在上面的代码中,我们首先判断新的角度是否与当前的角度相同。如果不同,我们就更新m_angle属性,并重新计算指针的位置。最后,我们调用update()函数来触发paintEvent()函数的调用,从而完成控件的重绘。 最后,我们可以在MainWindow类中使用我们的自定义控件,例如: ```C++ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { RotatingDial *dial = new RotatingDial(this); dial->setAngle(30); QHBoxLayout *layout = new QHBoxLayout; layout->addWidget(dial); setCentralWidget(new QWidget); centralWidget()->setLayout(layout); } ``` 在上面的代码中,我们创建了一个RotatingDial对象,并设置了初始角度为30度。然后,将其添加到QHBoxLayout布局中,并设置为主窗口的中央控件。 至此,我们已经完成了一个简单的旋转仪表盘自定义控件。你可以根据需要对其进行扩展和优化,使其更加适合你的应用场景。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

贝勒里恩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值