欢迎光临
我们一直在努力

Qt中自定义 QmyBattery 电池组件开发

在 Qt 开发中,自定义 Widget 是实现个性化 UI 组件的核心方式,本文以QmyBattery电池组件为例,详细讲解如何基于QWidget子类化实现具备电量显示、警告阈值、样式自定义的电池控件,涵盖核心绘制逻辑、属性封装、尺寸适配等关键知识点。

一、组件设计思路

QmyBattery组件需实现以下核心功能:

  • 可视化展示电池外形(主体 + 正极);
  • 按百分比显示电量填充效果,支持正常 / 警告颜色切换;
  • 封装电量、警告阈值等属性,支持外部设置 / 获取;
  • 自适应控件尺寸,保持电池外观比例协调;
  • 发射电量变化信号,支持与其他组件联动。
  • 二、核心代码实现

    1. 头文件(QmyBattery.h)

    #ifndef QMYBATTERY_H
    #define QMYBATTERY_H

    #include <QWidget>
    #include <QPainter>
    #include <QFontMetrics>

    class QmyBattery : public QWidget
    {
    Q_OBJECT
    // 注册属性,支持Qt属性系统(如UI设计师中编辑)
    Q_PROPERTY(int powerLevel READ powerLevel WRITE setPowerLevel)
    Q_PROPERTY(int warnLevel READ warnLevel WRITE setWarnLevel)
    Q_PROPERTY(QColor colorBoder READ colorBoder WRITE setColorBoder)
    Q_PROPERTY(QColor colorPower READ colorPower WRITE setColorPower)
    Q_PROPERTY(QColor colorWarning READ colorWarning WRITE setColorWarning)
    Q_PROPERTY(QColor colorBack READ colorBack WRITE setColorBack)

    public:
    explicit QmyBattery(QWidget *parent = nullptr);

    // 属性获取接口
    int powerLevel(); // 获取当前电量
    int warnLevel(); // 获取警告阈值
    QColor colorBoder(); // 获取边框颜色
    QColor colorPower(); // 获取正常电量颜色
    QColor colorWarning(); // 获取警告颜色
    QColor colorBack(); // 获取背景颜色

    // 属性设置接口
    void setPowerLevel(int pow); // 设置电量(触发重绘+信号)
    void setWarnLevel(int warn); // 设置警告阈值(触发重绘)
    void setColorBoder(QColor color);
    void setColorPower(QColor color);
    void setColorWarning(QColor color);
    void setColorBack(QColor color);

    // 重写尺寸提示,适配电池比例
    QSize sizeHint()const override;

    signals:
    void powerLevelChanged(int pow); // 电量变化信号

    protected:
    // 重写绘制事件,实现电池可视化
    void paintEvent(QPaintEvent *event) override;

    private:
    // 成员变量
    int mPowerLevel = 60; // 默认电量80%
    int mWarnLevel = 20; // 默认警告阈值20%
    QColor mColorBoder = Qt::black; // 边框颜色
    QColor mColorPower = Qt::green; // 正常电量颜色
    QColor mColorWarning = Qt::red; // 警告颜色
    QColor mColorBack = Qt::white; // 背景颜色
    };

    #endif // QMYBATTERY_H

    2. 源文件(QmyBattery.cpp)

    #include "QmyBattery.h"

    QmyBattery::QmyBattery(QWidget *parent) : QWidget(parent)
    {
    // 初始化无额外逻辑,属性使用默认值
    }

    // ========== 属性获取接口 ==========
    int QmyBattery::powerLevel()
    {
    return mPowerLevel;
    }

    int QmyBattery::warnLevel()
    {
    return mWarnLevel;
    }

    QColor QmyBattery::colorBoder()
    {
    return mColorBoder;
    }

    QColor QmyBattery::colorPower()
    {
    return mColorPower;
    }

    QColor QmyBattery::colorWarning()
    {
    return mColorWarning;
    }

    QColor QmyBattery::colorBack()
    {
    return mColorBack;
    }

    // ========== 属性设置接口 ==========
    void QmyBattery::setPowerLevel(int pow)
    {
    // 限制电量范围0-100,避免绘制异常
    mPowerLevel = qBound(0, pow, 100);
    emit powerLevelChanged(mPowerLevel); // 发射电量变化信号
    repaint(); // 触发重绘,更新显示
    }

    void QmyBattery::setWarnLevel(int warn)
    {
    mWarnLevel = qBound(0, warn, 100); // 限制阈值范围0-100
    repaint();
    }

    void QmyBattery::setColorBoder(QColor color)
    {
    mColorBoder = color;
    repaint();
    }

    void QmyBattery::setColorPower(QColor color)
    {
    mColorPower = color;
    repaint();
    }

    void QmyBattery::setColorWarning(QColor color)
    {
    mColorWarning = color;
    repaint();
    }

    void QmyBattery::setColorBack(QColor color)
    {
    mColorBack = color;
    repaint();
    }

    // ========== 尺寸适配 ==========
    QSize QmyBattery::sizeHint() const
    {
    // 保持电池宽高比12:5,适配任意控件高度
    int H = this->height();
    int W = H * 12 / 5;
    return QSize(W, H);
    }

    // ========== 核心绘制逻辑 ==========
    void QmyBattery::paintEvent(QPaintEvent *event)
    {
    Q_UNUSED(event); // 标记参数未使用,消除编译器警告
    QPainter painter(this);
    // 抗锯齿,使绘制边缘更平滑
    painter.setRenderHint(QPainter::Antialiasing);
    painter.setRenderHint(QPainter::TextAntialiasing);

    // 1. 设置绘制坐标系(视口+窗口,固定电池比例)
    QRect rect(0, 0, width(), height());
    painter.setViewport(rect); // 物理像素区域
    painter.setWindow(0, 0, 120, 50); // 逻辑坐标系(120×50)

    // 2. 绘制电池背景
    QBrush brush;
    QPen pen;
    pen.setWidth(2);
    pen.setColor(mColorBoder);
    pen.setStyle(Qt::SolidLine);
    painter.setPen(pen);

    brush.setColor(mColorBack);
    brush.setStyle(Qt::SolidPattern);
    painter.setBrush(brush);

    // 绘制电池主体背景
    QRect batteryRect(1, 1, 109, 48);
    painter.drawRect(batteryRect);
    // 绘制电池正极(顶部小矩形)
    QRect positiveRect(110, 15, 10, 20);
    painter.drawRect(positiveRect);

    // 3. 绘制电量填充
    if (mPowerLevel > mWarnLevel) {
    brush.setColor(mColorPower); // 正常电量颜色
    pen.setColor(mColorPower);
    } else {
    brush.setColor(mColorWarning); // 警告颜色
    pen.setColor(mColorWarning);
    }
    painter.setBrush(brush);
    painter.setPen(pen);

    // 电量>0时绘制填充矩形(宽度对应电量百分比)
    if (mPowerLevel > 0) {
    QRect powerRect(5, 5, mPowerLevel, 40);
    painter.drawRect(powerRect);
    }

    // 4. 绘制电量百分比文字(居中显示)
    QFontMetrics textSize(this->font());
    QString powStr = QString::asprintf("%d%%", mPowerLevel);
    QRect textRect = textSize.boundingRect(powStr);

    painter.setFont(this->font());
    pen.setColor(mColorBoder);
    painter.setPen(pen);
    // 文字居中计算:水平55-文字宽/2,垂直23+文字高/2
    painter.drawText(55 – textRect.width()/2, 23 + textRect.height()/2, powStr);
    }

    三、核心知识点解析

    1. 坐标系适配(setViewport/setWindow)

    通过setViewport(绑定控件物理尺寸)和setWindow(固定逻辑尺寸 120×50),实现电池控件无论拉伸 / 缩小时,始终保持 12:5 的宽高比,避免变形。

    2. 绘制分层逻辑

    组件绘制分为 4 层,层层叠加保证视觉效果:

    • 第 1 层:电池背景(白色 / 自定义背景色);
    • 第 2 层:电池边框 + 正极(黑色 / 自定义边框色);
    • 第 3 层:电量填充(绿色 / 红色,按阈值切换);
    • 第 4 层:电量百分比文字(居中显示,边框色保证对比度)。

    3. 属性封装与 Qt 属性系统

    通过Q_PROPERTY注册属性,使组件支持 Qt 属性系统:

    • 可在 UI 设计师中直接编辑电量、颜色等属性;
    • 支持信号与槽联动,如powerLevelChanged信号可绑定到其他组件响应电量变化。

    4. 尺寸适配(sizeHint)

    重写sizeHint返回按 12:5 比例计算的推荐尺寸,布局管理器(如 QVBoxLayout、QHBoxLayout)会优先使用该尺寸,保证组件布局协调。

    四、组件使用示例

    实现了QmyBattery类之后,若是用代码创建QmyBattery类对象,其使用与一般的组件类是一样的,若是在UI设计器中使用QmyBattery,则需要采用提升法,在窗体上放置一个QWidget类组件,然后鼠标右键调出菜单“提升…”

    在基类名称下选择QWidget,将提升后的类名称设置为QmyBattery,单击Add ,单击Promote,提升后在属性将组件名称修改为qmyBattery

    再放置4个按钮用来测试这个电池组件。

    void MainWindow::on_pushButton_clicked()
    {
    ui->qmyBattery->setPowerLevel(70);
    }

    void MainWindow::on_pushButton_2_clicked()
    {
    ui->qmyBattery->setPowerLevel(10);
    }

    void MainWindow::on_pushButton_3_clicked()
    {
    ui->qmyBattery->setPowerLevel(100);
    }

    void MainWindow::on_pushButton_4_clicked()
    {
    ui->qmyBattery->setPowerLevel(0);
    }

    默认电量60%

    设置电量100%

    设置电量70%

    设置电量10%

    设置电量0

    总结

    QmyBattery组件通过子类化QWidget,重写paintEvent实现核心绘制逻辑,封装属性与信号保证组件的可复用性和交互性。核心要点包括:

  • 利用 Qt 绘图框架实现分层绘制,保证视觉层次清晰;
  • 通过坐标系适配和sizeHint实现组件尺寸自适应;
  • 遵循 Qt 属性系统设计规范,提升组件易用性;
  • 核心逻辑解耦(绘制 / 属性 / 信号分离),便于扩展维护。
  • 该组件可直接集成到 Qt 项目中,适用于电量显示、设备状态监控等场景,是 Qt 自定义 Widget 开发的典型实践。

    赞(0)
    未经允许不得转载:171主机测评 » Qt中自定义 QmyBattery 电池组件开发
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址