Qt(C++)绘制指针仪表盘显示当前温度
一、功能介绍
当前文章要实现的功能:
使用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
类型。
- 点赞
- 收藏
- 关注作者
评论(0)