《Qt/UI美化实战课程》| 第五章 自定义仪表盘(美观/高度定制/自适应大小)| 8. 使用仪表盘(7) 让仪表盘动起来

 《Qt/UI美化实战课程》新课首发

(1)无边框窗口(11讲)

(2)图标字体(10讲)

(3)官方图表QChart:曲线、柱状图、饼图(20+讲)

(4)第三方图表QCustomPlot:曲线、柱状图、饼图(20+讲)

(5)监控日志高亮(共 14 讲)

(6)仪表盘(16讲)

(7)天气预报(11+讲)

(8)基础控件(15+讲)

(9)高级控件(12+讲)

(10)精美换肤(15+讲)

详情参见个人主页的置顶视频(明王出品,必属精品)

需要系统跟明王学习的小伙伴:coding4096

(1)总课时:超 120+ 讲,每日更新

(2)讲课风格:从零新建项目,从零一行行写代码

(3)提供资料:视频教程+配套源码+详细笔记

本章将会从零实现一个自定义控件-仪表盘,它支持:

✅ 自定义起始角度、圆弧跨度

✅ 自定义圆环宽度、颜色、样式

✅ 支持背景圆环、当前值圆环

✅ 自定义刻度线的颜色、位置、大小刻度的数目

✅ 自定义刻度值的颜色、位置、最大最小值、精度(小数位数)

✅ 自定义显示标题:温度、湿度、电流、电压等(标题完美地显示在缺口处)

✅ 支持动画特性:从一个值变为另一个值,指针会平滑旋转

✅ 支持仪表盘自适应大小(仪表盘缩放时,圆环宽度、刻度线、刻度值、标题大小等,自适应地缩放)

本章会从零开始,自定义实现一个仪表盘控件。会实现的2个效果:

这里做一个动态的效果,如下:

1. 增加动起来复选框

首先,来到 widget.h,增加一个复选框以及其对应的槽函数,如下:

class Widget : public QWidget
{
private slots:
    // 动起来
    void onChkShowClicked(bool b);

private:
    // 动起来
    QCheckBox* chkShow;
};

然后,来到 widget.cpp,修改 initRight() 函数,如下:

void Widget::initRight()
{
    // 5. 弹簧
    QSpacerItem* item = new QSpacerItem(1, 1, QSizePolicy::Fixed, QSizePolicy::Expanding);
    rightLayout->addItem(item);

    // 6. 动态效果展示
    QGroupBox* showGroup = new QGroupBox("炫酷动画展示", this);

    QHBoxLayout* showLayout = new QHBoxLayout(showGroup);
    chkShow = new QCheckBox(this);
    showLayout->addWidget(chkShow);

    rightLayout->addWidget(showGroup);
}

最后,来到 widget.cpp,在构造中,绑定复选框的槽函数,如下:

Widget::Widget(QWidget* parent) : QWidget(parent)
{
    // 5. 动起来
    connect(chkShow, SIGNAL(toggled(bool)), this, SLOT(onChkShowClicked(bool)));
}
 

2. 让角度动起来

首先,来到 widget.h,声明相关的成员函数和成员变量,如下:

class Widget : public QWidget
{
private slots:
    // 动起来
    void onStartAngleTimeout();

private:
    // 动起来
    // 角度
    QTimer* startAngleTimer;
    bool incStartAngle;
    int cnt;
};
 

然后,来到 widget.cpp,实现 onStartAngleTimeout() 槽函数,如下:

void Widget::onStartAngleTimeout()
{
    int startAngle = gauge->getStartAngle();

    if ( incStartAngle ) {
        startAngle++;
        if ( startAngle >= 360 ) {
            incStartAngle = false;
            startAngle = 359;
        }
    } else {
        startAngle--;
        if ( startAngle <= 0 ) {
            incStartAngle = true;
            startAngle = 0;
        }
    }
    gauge->setStartAngle(startAngle);  // 设置起始角度
    leStartAngle->setText(QString::number(startAngle));
}
不要忘记在 widget.cpp 构造中,创建定时器,绑定超时的槽函数,如下:
Widget::Widget(QWidget* parent) : QWidget(parent)
{
    // 5. 动起来
    startAngleTimer = new QTimer(this);
    incStartAngle = true;
    connect(startAngleTimer, &QTimer::timeout, this, &Widget::onStartAngleTimeout);
}
最后,实现 onChkShowClicked() 函数,如下:
void Widget::onChkShowClicked(bool b)
{
    if ( b ) {
        startAngleTimer->start(100);
    } else {
        startAngleTimer->stop();
    }
}
此时运行,效果如下:

3. 让值动起来

首先,来到 widget.h,声明相关的成员函数和成员变量,如下:

class Widget : public QWidget
{
private slots:
    // 动起来
    void onValueTimeout();

private:
    // 动起来
    // 值
    QTimer* valueTimer;
    bool incValue;
};
然后,来到 widget.cpp,实现 onValueTimeout() 槽函数,如下:
void Widget::onValueTimeout()
{
    QColor colors[4] = {QColor(89, 113, 201), QColor(221, 99, 98), QColor(156, 204, 108), QColor(240, 198, 65)};
    PointerStyle pointerStyle[4] = {Circle, Sharp, Circle, Sharp};
    Qt::PenCapStyle ringStyle[4] = {Qt::RoundCap, Qt::FlatCap, Qt::RoundCap, Qt::FlatCap};

    float value = gauge->getValue();
    float step = (gauge->getMaxValue() - gauge->getMinValue()) / (gauge->getMajorScale() * gauge->getMinorScale());
    if ( incValue ) {
        value += step;
        if ( value > gauge->getMaxValue() ) {
            value = gauge->getMaxValue();
            incValue = false;
        }
    } else {
        value -= step;
        if ( value < gauge->getMinValue() ) {
            value = gauge->getMinValue();
            incValue = true;

            cnt = (cnt + 1) % 4;
            gauge->setCurrentRingColor(colors[cnt]);  // 设置当前圆环颜色
            QString currentRingColor = QString("background-color: rgb(%1,%2,%3);").arg(colors[cnt].red()).arg(colors[cnt].green()).arg(colors[cnt].blue());
            lblCurrentRingColor->setStyleSheet(currentRingColor);

            gauge->setPointerColor(colors[cnt]);  // 设置指针颜色
            QString pointerColor = QString("background-color: rgb(%1,%2,%3);").arg(colors[cnt].red()).arg(colors[cnt].green()).arg(colors[cnt].blue());
            lblPointerColor->setStyleSheet(pointerColor);

            gauge->setPointerStyle(pointerStyle[cnt]);
            if ( pointerStyle[cnt] == Circle ) {
                cboPointerStyle->setCurrentIndex(0);
            } else if ( pointerStyle[cnt] == Sharp ) {
                cboPointerStyle->setCurrentIndex(1);
            }

            gauge->setRingStyle(ringStyle[cnt]);
            if ( ringStyle[cnt] == Qt::FlatCap ) {
                cboRingStyle->setCurrentIndex(0);
            } else if ( ringStyle[cnt] == Qt::RoundCap ) {
                cboRingStyle->setCurrentIndex(1);
            }
        }
    }
    gauge->setValue(value);

    int sliderValue = (value - gauge->getMinValue()) / (gauge->getMaxValue() - gauge->getMinValue()) * (slider->maximum() - slider->minimum());
    slider->setValue(sliderValue);
}
不要忘记在 widget.cpp 构造中,创建定时器,绑定超时的槽函数,如下:
Widget::Widget(QWidget* parent) : QWidget(parent)
{
    // 5. 动起来
    valueTimer = new QTimer(this);
    incValue = true;
    cnt = 0;
    connect(valueTimer, &QTimer::timeout, this, &Widget::onValueTimeout);
}

最后,修改 onChkShowClicked() 函数,如下:

void Widget::onChkShowClicked(bool b)
{
    if ( b ) {
        startAngleTimer->start(100);
        valueTimer->start(100);
    } else {
        startAngleTimer->stop();
        valueTimer->stop();
    }
}
此时运行,就可以实现开始展示的动画效果了,如下:

<think>好的,我需要回答用户关于Qt6安装是否需要Qt Quick组件的问题,并解释其使用场景。首先,用户提到他们参考的引用内容涉及Qt Quick的概述、安装维护工具以及Qt Quick模块的组成。我需要结合这些信息来给出准确的回答。 首先,根据引用[4],Qt Quick模块是用于编写QML应用的标准库,提供了QML和C++接口。这说Qt Quick在开发QML应用时是必需的。如果用户计划使用QML来构建用户界面,那么安装Qt Quick组件是必要的。 接着,引用[1]提到使用维护工具进行卸载,这可能涉及到组件选择的问题。在安装Qt6时,用户可以通过维护工具选择需要安装的组件。如果不需要QML开发,可能可以不安装Qt Quick,但通常默认安装可能包含基础模块。 然后,用户的问题是关于Qt6安装Qt Quick的必要性。需要Qt Quick是否是默认安装的一部分,或者是否需要手动选择。根据经验,Qt Quick通常是Qt核心模块的一部分,尤其在Qt6中,QML和Qt Quick的集成更为紧密,可能默认包含在基础安装中,但具体可能取决于安装时的组件选择。 此外,引用[3]和[4]都强调了Qt Quick在创建动态用户界面中的作用。如果用户的项目需要前端UI设计,尤其是声式的QML界面,那么Qt Quick是必不可少的。反之,如果仅进行控制台应用或不需要UI的后端开发,可能不需要安装。 需要注意的是,某些Qt模块可能依赖Qt Quick,比如Qt Quick Controls或Qt Quick 3D。如果用户需要这些高级功能,则必须安装Qt Quick组件。 总结来说,回答应分点说必要性取决于项目需求,如果涉及QML UI开发则需要,否则可能不需要,并列举使用场景如QML应用、动态界面、与其他模块的依赖等。同时,引用相关的资料来支持结论,例如引用[4]中关于Qt Quick模块的作用。 最后,生成相关问题,帮助用户进一步了解Qt Quick的相关内容,比如安装方法、与其他模块的关系等。</think>在Qt6中,是否安装Qt Quick组件取决于具体开发需求。以下是关键分析: ### 1. Qt Quick的必要性 - **必须安装的场景**: - 使用QML语言开发声式用户界面时,Qt Quick是基础运行时库[^4] - 需要创建动态交云界面、动画效果或响应式布局 - 使用Qt Quick Controls、Qt Quick 3D等扩展模块时(存在依赖关系) - **可不安装的场景**: - 仅开发控制台程序或无UI的后端服务 - 使用传统Qt Widgets进行界面开发 ### 2. Qt6的组件变化 Qt6将Qt Quick拆分为更细粒度的模块(如`QtQuick`、`QtQuick.Window`),安装时可通过`Qt 6.X.Y`分类下的子组件勾选。基础安装包通常包含核心模块,但完整QML开发建议勾选: ``` Qt Quick 2.x Qt Quick Controls 2.x Qt Quick Layouts Qt Quick Templates ``` ### 3. 使用场景示例 - **跨平台移动应用**:通过QML+Qt Quick实现自适应布局 - **工业HMI界面**:结合Qt Quick 3D实现三维可视化面板[^2] - **嵌入式仪表盘**:利用硬件加速渲染特性 ```qml // 示例:QML旋转矩形 import QtQuick 2.15 Rectangle { width: 100; height: 100 color: "blue" RotationAnimation on rotation { from: 0; to: 360; duration: 2000 loops: Animation.Infinite } } ``` ### 4. 验证安装状态 通过`Qt Maintenance Tool`(引用[1]提到的维护工具)检查已安装组件: 1. 打开维护工具选择「添加或移除组件」 2. 展开`Qt 6.X.Y`分类 3. 查看`Qt Quick`相关模块的勾选状态
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

大轮明王讲QT

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

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

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

打赏作者

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

抵扣说明:

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

余额充值