写点什么

Qt(C++) 绘制指针仪表盘显示当前温度

作者:DS小龙哥
  • 2024-06-27
    重庆
  • 本文字数:3336 字

    阅读完需:约 11 分钟

一、功能介绍

当前文章要实现的功能:


使用 Qt 绘制一个仪表盘,用来显示当前的温度,绘制刻度、绘制数字、绘制温度指针。仪表盘全程使用 QPainter 进行绘制,QPainter 是 Qt 框架中非常重要的一个类,绘制功能的实现离不开它。如果想要使用 Qt 进行高质量的绘图或 UI 设计,必须掌握 QPainter 的使用方法。


QPainter 的简介:


QPainter 是 Qt 里用于绘制图形的类,提供了各种绘制函数,可以绘制几何图形、文本、图片等等。QPainter 所绘制的图形可以在 QWidget 及其子类的 paintEvent()事件中使用,也可以在 QPixmap 等其他对象中进行绘制。


QPainter 的大致使用流程如下:


1. 创建一个QPainter对象,需要传入一个绘制设备,例如QWidget或QPixmap。2. 用QPainter的各种绘制函数来绘制几何图形、文本、图片等等。3. 在绘制完成后,将画笔和画刷等状态还原到初始状态。4. 在必要时释放QPainter对象。
复制代码


温度仪表盘最终绘制出的效果--带数字刻度:




无数字刻度效果:


二、代码设计过程

【1】定义一个自定义控件 my_DrawDashboard,继承 QWidget 类


class my_DrawDashboard : public QWidget{    Q_OBJECT
public: explicit my_DrawDashboard(QWidget *parent = nullptr); ~my_DrawDashboard();
protected: void paintEvent(QPaintEvent *event) override;
private: int m_temperature;
signals: void temperatureChanged(int temperature);
public slots: void setTemperature(int temperature);};
复制代码


【2】在 my_DrawDashboard 的构造函数中初始化温度及其他属性值


MyWidget::MyWidget(QWidget *parent)    : QWidget(parent){    m_temperature = 0;    setMinimumSize(200, 200);    setMaximumSize(200, 200);}
复制代码


【3】在 my_DrawDashboard 中实现 paintEvent()函数,绘制仪表盘


void my_DrawDashboard::paintEvent(QPaintEvent *event){    Q_UNUSED(event)
// 定义画布和画笔 QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); int w = width(); int h = height(); int radius = qMin(w, h) / 2; QPoint center(w / 2, h / 2); QFont font("Arial", radius * 0.1, QFont::Bold); painter.setFont(font);
// 绘制背景圆 painter.setPen(Qt::NoPen); painter.setBrush(QColor("#EEEEEE")); painter.drawEllipse(center, radius, radius);
// 绘制刻度 painter.setPen(QPen(Qt::black, radius * 0.02)); for (int i = 0; i <= 10; ++i) { int angle = i * 30; painter.drawLine(center + QPoint(radius * cos(angle * M_PI / 180.0), radius * sin(angle * M_PI / 180.0)), center + QPoint((radius - radius * 0.15) * cos(angle * M_PI / 180.0), (radius - radius * 0.15) * sin(angle * M_PI / 180.0))); }
// 绘制温度指针 painter.setPen(QPen(Qt::red, radius * 0.05)); painter.setBrush(Qt::red); painter.save(); int angle = -135 + m_temperature * 27 / 5; painter.rotate(angle); QPointF pointer[3] = { center + QPoint(radius * 0.05, 0), center + QPoint(-radius * 0.05, 0), center + QPoint(0, -radius * 0.9) }; painter.drawConvexPolygon(pointer, 3); painter.restore();
// 绘制当前温度值 painter.setPen(Qt::black); painter.drawText(QRectF(center.x() - radius * 0.5, center.y() + radius * 0.2, radius, radius), Qt::AlignCenter, QString("%1℃").arg(m_temperature));}
复制代码


【4】在 my_DrawDashboard 中提供一个 setTemperature()函数,用于更新当前温度并触发 temperatureChanged 信号


void my_DrawDashboard::setTemperature(int temperature){    if (m_temperature == temperature)        return;
m_temperature = temperature; update(); emit temperatureChanged(m_temperature);}
复制代码


【5】使用 QTimer 来模拟温度的变化,并实时更新仪表盘的显示


// 在主窗口中创建my_DrawDashboard控件my_DrawDashboard *widget = new my_DrawDashboard(this);
// 创建QTimer对象并绑定温度变化槽函数QTimer *timer = new QTimer(this);connect(timer, &QTimer::timeout, this, [&widget](){ int temperature = qrand() % 31 - 10; widget->setTemperature(temperature);});
// 启动定时器timer->start(1000);
复制代码


上面代码中,在主窗口中创建了一个 my_DrawDashboard 控件,使用 QTimer 对象来模拟温度的变化。每隔 1 秒钟生成一个随机的温度值,调用 my_DrawDashboard 的 setTemperature()函数来更新当前温度,并实时更新仪表盘的显示。

三、完整的工程

【1】my_DrawDashboard.cpp

#include "my_drawdashboard.h"
my_DrawDashboard::my_DrawDashboard(QWidget *parent) : QWidget(parent){ m_temperature = 0; //setMinimumSize(100, 100); // setMaximumSize(100, 100);}


void my_DrawDashboard::paintEvent(QPaintEvent *event){ Q_UNUSED(event)
// 定义画布和画笔 QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); int w = width(); int h = height(); int radius = qMin(w, h) / 2; QPoint center(w / 2, h / 2); QFont font("Arial", radius * 0.1, QFont::Bold); painter.setFont(font);
// 绘制背景圆 painter.setPen(Qt::NoPen); painter.setBrush(QColor("#EEEEEE")); painter.drawEllipse(center, radius, radius);
// 绘制刻度 painter.setPen(QPen(Qt::black, radius * 0.02)); for (int i = 0; i <= 10; ++i) { int angle = i * 30; painter.drawLine(center + QPoint(radius * cos(angle * M_PI / 180.0), radius * sin(angle * M_PI / 180.0)), center + QPoint((radius - radius * 0.15) * cos(angle * M_PI / 180.0), (radius - radius * 0.15) * sin(angle * M_PI / 180.0))); }
// 绘制温度指针 painter.setPen(QPen(Qt::red, radius * 0.05)); painter.setBrush(Qt::red); painter.save(); int angle = -135 + m_temperature * 27 / 5;
//painter.rotate(60); QPointF pointer[3] = { center + QPoint(radius * 0.05, 0), center + QPoint(-radius * 0.05, 0), center + QPoint(0, -radius * 0.9) }; painter.drawConvexPolygon(pointer, 3); painter.restore();
// 绘制当前温度值 painter.setPen(Qt::black); painter.drawText(QRectF(center.x() - radius * 0.5, center.y() + radius * 0.2, radius, radius), Qt::AlignCenter, QString("%1℃").arg(m_temperature));}

void my_DrawDashboard::setTemperature(int temperature){ if (m_temperature == temperature) return;
m_temperature = temperature; update(); emit temperatureChanged(m_temperature);}
复制代码

【2】my_DrawDashboard.h

#ifndef MY_DRAWDASHBOARD_H#define MY_DRAWDASHBOARD_H
#include <QWidget>#include <QPainter>#include <qmath.h>
class my_DrawDashboard : public QWidget{ Q_OBJECT
public: explicit my_DrawDashboard(QWidget *parent = nullptr); //~my_DrawDashboard();protected: void paintEvent(QPaintEvent *event) override;
private: int m_temperature=20;
signals: void temperatureChanged(int temperature);
public slots: void setTemperature(int temperature);};

#endif // MY_DRAWDASHBOARD_H
复制代码

【3】设计 UI 界面

在主窗口上,拖拽一个 QWidget 控件,提升为my_DrawDashboard类型。




发布于: 18 分钟前阅读数: 5
用户头像

DS小龙哥

关注

微信公众号:DS小龙哥嵌入式技术资讯 2022-01-06 加入

所有项目文章对应的工程源码,都可以在我的微信公众号:《DS小龙哥嵌入式技术资讯》 里下载。

评论

发布
暂无评论
Qt(C++)绘制指针仪表盘显示当前温度_6 月 优质更文活动_DS小龙哥_InfoQ写作社区