找回密码
 立即注册
首页 业界区 安全 Qt自定义控件与提升法(prompted)

Qt自定义控件与提升法(prompted)

莅耸 2025-6-1 19:06:40
Qt自定义控件与提升法(prompted)

需求:

我们需要自定义UI组件, 同时还想在Desiginer上通过拖拽搭建界面.
方法:


  • 继承widget类, 用QPainer自已绘制界面.
  • 在Desiginer中, 使用QWidget做为占位符, 并把这个占位QWidget提升为我们的自定义组件.
例子:

这里举一个自定义电池UI的例子展示自定义组件和提升方法.
自定义UI

首先, 我们从Widget继承出TBattey类, 用QPainter来画一个能根据电量值变化长度的矩形框来表示电池电量.
  1. #ifndef TBATTERY_H
  2. #define TBATTERY_H
  3. #include <QWidget>
  4. class TBattery : public QWidget
  5. {
  6.     Q_OBJECT
  7.     Q_PROPERTY(int m_power READ powerLevel WRITE setPowerLevel NOTIFY powerLevelChanged)
  8. private:
  9.     int m_power;
  10. public:
  11.     explicit TBattery(QWidget *parent = nullptr);
  12.     int powerLevel();
  13.     bool setPowerLevel(int v);
  14. protected:
  15.     void paintEvent(QPaintEvent *event);
  16. signals:
  17.     void powerLevelChanged(int);
  18. public slots:
  19.     void update_Power(int);
  20. };
  21. #endif // TBATTERY_H
复制代码
  1. #include "tbattery.h"
  2. #include <QLabel>
  3. #include <QPainter>
  4. #include <QRect>
  5. TBattery::TBattery(QWidget *parent)
  6.     : QWidget{parent}
  7. {}
  8. int TBattery::powerLevel()
  9. {
  10.     return this->m_power;
  11. }
  12. bool TBattery::setPowerLevel(int v)
  13. {
  14.     this->m_power = v;
  15.     return true;
  16. }
  17. void TBattery::paintEvent(QPaintEvent *event)
  18. {
  19.     QPainter painter(this);
  20.     QRect rect(0, 0, width(), height());
  21.     # 设置显示范围是整个组件
  22.     painter.setViewport(rect);
  23.     # 设置虚拟座标轴的范围
  24.     painter.setWindow(0, 0, 120, 50);
  25.     Qt::GlobalColor color = Qt::green;
  26.     if (this->m_power >= 20 && this->m_power <= 50)
  27.         color = Qt::yellow;
  28.     if (this->m_power <= 20)
  29.         color = Qt::red;
  30.     QPen pen(color);
  31.     pen.setWidth(2);
  32.     painter.setPen(pen);
  33.     painter.setBrush(color);
  34.     int L = (int) (120 * (this->m_power / 100.0));
  35.     painter.drawRect(QRect(0, 0, L, 48));
  36. }
  37. void TBattery::update_Power(int x)
  38. {
  39.     if (x >= 100)
  40.         x = 100;
  41.     if (x <= 0)
  42.         x = 0;
  43.     this->setPowerLevel(x);
  44.     qDebug() << this->m_power;
  45.     this->update();
  46.     emit this->powerLevelChanged(this->m_power);
  47. }
复制代码
提升法在Designer中拖拽组件

接下来我们在UI界面上拖一个Widget组件, 这个Widget组件是空的什么都不会显示.
1.png

我们在这个组件上右键选择 prompt to..., 并添加 prompted classes.
这里的类名就是我们的自定义组件的类名 TBattery , Header file 是TBattery类的头文件位置.
2.png

我们可以看到这个组件的类型已经从QWidget变成了TBattery, 在运行程序时就会显示我们画的电池UI.
3.png

编译运行项目, 我们可以看到界面中原本用来占位的QWidget变成了我们自定义的TBattery类.
4.png

有时, QtCreater并不会帮我们把头文件链入cmake文件中, 编译时会显示找不到TBattery.h这个头文件, 这时我们需要在CMakeLists.txt中加上include_directories .
  1. include_directories(
  2.   ${PROJECT_SOURCE_DIR}
  3. )
复制代码
不足:

使用prompted方法在Designer中使用自定义组件非常的简单, 不足之处是不能在desinger中实时的显示自定义的UI, 也不能用deisigner的图形界面设置信号量.
进一步的解决办法是把组件写成插件的形式让qt creater载入, 这样可以用上qt designer中的所有功能.
更多: https://www.codebonobo.tech/post/Qt%E8%87%AA%E5%AE%9A%E4%B9%89%E6%8E%A7%E4%BB%B6%E4%B8%8E%E6%8F%90%E5%8D%87%E6%B3%95(prompted)

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册