Qt (C++) dibuja el tablero del puntero para mostrar la temperatura actual

1. Introducción a la función

Las funciones a implementar en el presente artículo:

Use Qt para dibujar un tablero para mostrar la temperatura actual, dibujar escalas, dibujar números y dibujar indicadores de temperatura. El tablero se dibuja utilizando QPainter en todo momento.QPainter es una clase muy importante en el marco de Qt, y la realización de la función de dibujo no se puede separar de ella. Si desea usar Qt para el dibujo de alta calidad o el diseño de la interfaz de usuario, debe dominar el uso de QPainter.

Introducción a QPainter:

QPainter es una clase que se usa para dibujar gráficos en Qt. Proporciona varias funciones de dibujo, que pueden dibujar figuras geométricas, texto, imágenes, etc. Los gráficos dibujados por QPainter se pueden usar en el evento paintEvent() de QWidget y sus subclases, y también se pueden dibujar en otros objetos como QPixmap.

El proceso de uso general de QPainter es el siguiente:

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

El efecto final del tablero de temperatura - con escalas digitales:

imagen-20230530163418909

imagen-20230530164040271

Sin efecto de escala numérica:

imagen-20230530161040237

2. Proceso de diseño de código

[1] Definir un control personalizado my_DrawDashboard, heredando la clase 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] Inicialice la temperatura y otros valores de atributos en el constructor de my_DrawDashboard

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

[3] Implemente la función paintEvent() en my_DrawDashboard para dibujar el tablero

 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] Proporcione una función setTemperature() en my_DrawDashboard para actualizar la temperatura actual y activar la señal de cambio de temperatura

 void my_DrawDashboard::setTemperature(int temperature)
 {
     if (m_temperature == temperature)
         return;
 ​
     m_temperature = temperature;
     update();
     emit temperatureChanged(m_temperature);
 }

[5] Use QTimer para simular cambios de temperatura y actualizar la pantalla del tablero en tiempo real

 // 在主窗口中创建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);

En el código anterior, se crea un control my_DrawDashboard en la ventana principal y se usa un objeto QTimer para simular el cambio de temperatura. Genere un valor de temperatura aleatorio cada 1 segundo, llame a la función setTemperature() de my_DrawDashboard para actualizar la temperatura actual y actualice la visualización del tablero en tiempo real.

3. Proyecto completo

【1】mi_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】mi_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】Interfaz de interfaz de usuario de diseño

En la ventana principal, arrastre un control QWidget y promuévalo a my_DrawDashboardtipo.

imagen-20230530161716856

imagen-20230530161843349

Supongo que te gusta

Origin juejin.im/post/7240333779223281720
Recomendado
Clasificación