【Qt绘制仪表盘】

目的

使用Qt的绘制事件绘制一个仪表盘

思路

  1. 需要创建一个带绘制事件的控件
  2. 重写绘制事件
  3. 显示

实现

以下是实现代码,可复制到程序到,直接运行。

.h
cpp 复制代码
// GaugeWidget.h
#ifndef GAUGEWIDGET_H
#define GAUGEWIDGET_H

#include <QWidget>

class GaugeWidget : public QWidget
{
    Q_OBJECT
public:
    explicit GaugeWidget(QWidget *parent = nullptr);

    void setValue(qreal value){m_value = value;}

protected:
    void paintEvent(QPaintEvent *event) override;

private:
    qreal m_value;
};

#endif // GAUGEWIDGET_H
.h分析
  • 继承QWidget类,重新实现void paintEvent(QPaintEvent *event) override;事件;
  • 设置仪表盘当前的数据void setValue(qreal value){m_value = value;}
.cpp
cpp 复制代码
// GaugeWidget.cpp
#include "GaugeWidget.h"
#include <QPainter>

#include <QDebug>
GaugeWidget::GaugeWidget(QWidget *parent) : QWidget(parent), m_value(0)
{

}

void GaugeWidget::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event);

    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);

    qDebug().noquote() << "[" << __FILE__ << __LINE__ << "]" << this->size();
    // 绘制表盘
    painter.save();
    painter.translate(width()/2, height()/2);
    painter.setPen(Qt::NoPen);
    painter.setBrush(QBrush(QColor(255, 255, 255)));
    painter.drawEllipse(-100, -100, 200, 200);
    painter.setBrush(QBrush(QColor(200, 200, 200)));
    painter.drawEllipse(-95, -95, 190, 190);

    static const int majorTickCount = 12;
    static const int minorTickCount = 5;

    QFont font;
    font.setPointSize(8);
    painter.setFont(font);

    painter.save();
    for (int i = 0; i <= majorTickCount; i++) {
        qreal angle = i * 360.0 / majorTickCount;
        painter.rotate(angle);

        // 绘制刻度线
        if (i < majorTickCount) {
            painter.setPen(QPen(QColor(255, 255, 255), 2));
            painter.drawLine(0, -85, 0, -95);
        }

        // 绘制刻度值
        if (i % 2 == 0) {
            painter.setPen(QPen(QColor(255, 0, 0)));
            qreal value = i * 360.0 / majorTickCount;
            QString text = QString::number(value, 'f', 0);
            QRectF textRect(-50, -100, 100, 100);
            painter.drawText(textRect, Qt::AlignTop|Qt::AlignHCenter, text);
        }

        painter.rotate(-angle);
    }

    for (int i = 0; i < majorTickCount; i++) {
        for (int j = 1; j <= minorTickCount; j++) {
            qreal angle = (i + j / (qreal)minorTickCount) * 360.0 / majorTickCount;
            painter.save();
            painter.rotate(angle);

            painter.setPen(QPen(QColor(255, 255, 255), 1));
            painter.drawLine(0, -90, 0, -95);

            painter.restore();
        }
    }
    painter.restore();

    // 绘制指针
    qreal angle = (m_value / 60.0+0.5) * 360;
    painter.rotate(angle);
    painter.setPen(QPen(QColor(255, 0, 0), 3));
    painter.drawLine(0, 0, 0, 60);
    painter.restore();
}
.cpp分析

paintEvent函数是继承自QWidget的paintEvent事件处理函数,用于绘制小部件的界面。paintEvent函数首先创建一个QPainter对象,然后设置抗锯齿渲染。其余部分主要是绘制仪表盘和指针。具体绘制过程如下:

  1. 绘制表盘:
  • 将绘图原点平移到小部件的中心。

  • 绘制外圆和内圆,用QBrush用来填充圆形。

  • 根据majorTickCount(12)的值循环绘制刻度线和刻度值。每次循环需要计算出角度,然后将绘图原点旋转该角度。

  • 如果当前是大刻度线,则用QPen绘制白色线条。

  • 如果当前是大刻度线的偶数,则用QPen绘制红色刻度值,绘制完成后将绘图原点旋转回来。

  • 根据majorTickCount(12)和minorTickCount(5)的值循环绘制小刻度线。每次循环需要计算出角度,然后将绘图原点旋转该角度,绘制小刻度线,然后将绘图原点旋转回来。

  1. 绘制指针:
  • 根据m_value的值计算出指针应该指向的角度,并将绘图原点旋转该角度。
  • 用QPen绘制红色的指针线。
  • 将绘图原点旋转回来。
在MainWindow中使用自定义控件类GaugeWidget,测试表盘绘制效果:
cpp 复制代码
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "GaugeWidget.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    GaugeWidget *gaugeWidget = new GaugeWidget;
    setCentralWidget(gaugeWidget);
    gaugeWidget->setValue(40);
}

MainWindow::~MainWindow()
{
    delete ui;
}
编译运行程序,效果如下:

结论

繁华到极致,腐朽到荒凉

相关推荐
Swift社区1 小时前
在 Swift 中实现字符串分割问题:以字典中的单词构造句子
开发语言·ios·swift
没头脑的ht1 小时前
Swift内存访问冲突
开发语言·ios·swift
没头脑的ht2 小时前
Swift闭包的本质
开发语言·ios·swift
wjs20242 小时前
Swift 数组
开发语言
stm 学习ing3 小时前
FPGA 第十讲 避免latch的产生
c语言·开发语言·单片机·嵌入式硬件·fpga开发·fpga
湫ccc3 小时前
《Python基础》之字符串格式化输出
开发语言·python
mqiqe4 小时前
Python MySQL通过Binlog 获取变更记录 恢复数据
开发语言·python·mysql
AttackingLin4 小时前
2024强网杯--babyheap house of apple2解法
linux·开发语言·python