Qt之实现自定义控件的两种方式——插件法


前言

  可以通过Qt设计师拖拽原生控件进行界面开发,但有时候原生控件不能满足项目需求。此时,就需要实现自定义控件。
  Qt中实现自定义控件,有两种方式,即提升法和插件法。本篇介绍插件法。

一、需求

  同上一篇一样,自定义实现一个电池电量显示控件,可以通过设置参数的方式修改电池电量值。电量值等级不同,颜色不同。
  低电量时,效果如下:
在这里插入图片描述
  电量较高或满电时,效果如下:
在这里插入图片描述

二、实现

1、新建项目

  新建项目,选择“其他项目”,如下:
请添加图片描述
  项目名称为“myBatteryPlugin”,如下:
请添加图片描述
  一直下一步,命名自定义控件类类名为myBattery,控件基类为QWidget,插件类名为myBatteryPlugin,设置插件图标,如下:
请添加图片描述
  下一步,命名插件名称为mybatteryplugin,如下:
请添加图片描述
  点击下一步,直至项目创建完成,工程组织结构如下:
在这里插入图片描述

2、自定义控件类

  新建一个自定义控件类,类名为myBattery,继承于QWidget类,该类主要负责实现自定义控件,注意此处使用Q_DECL_EXPORT 宏。
  核心代码如下:

class Q_DECL_EXPORT myBattery : public QWidget
{
    Q_OBJECT
    Q_PROPERTY(double minValue READ getMinValue WRITE setMinValue)
    Q_PROPERTY(double maxValue READ getMaxValue WRITE setMaxValue)
    Q_PROPERTY(double value READ getValue WRITE setValue)
    Q_PROPERTY(double alarmValue READ getAlarmValue WRITE setAlarmValue)

    Q_PROPERTY(double step READ getStep WRITE setStep)
    Q_PROPERTY(int borderWidth READ getBorderWidth WRITE setBorderWidth)
    Q_PROPERTY(int borderRadius READ getBorderRadius WRITE setBorderRadius)
    Q_PROPERTY(int bgRadius READ getBgRadius WRITE setBgRadius)
    Q_PROPERTY(int headRadius READ getHeadRadius WRITE setHeadRadius)

    Q_PROPERTY(QColor borderColorStart READ getBorderColorStart WRITE setBorderColorStart)
    Q_PROPERTY(QColor borderColorEnd READ getBorderColorEnd WRITE setBorderColorEnd)

    Q_PROPERTY(QColor alarmColorStart READ getAlarmColorStart WRITE setAlarmColorStart)
    Q_PROPERTY(QColor alarmColorEnd READ getAlarmColorEnd WRITE setAlarmColorEnd)

    Q_PROPERTY(QColor normalColorStart READ getNormalColorStart WRITE setNormalColorStart)
    Q_PROPERTY(QColor normalColorEnd READ getNormalColorEnd WRITE setNormalColorEnd)

public:
    explicit myBattery(QWidget *parent = 0);
    ~myBattery();

signals:
    void valueChanged(double value);

private slots:
    void updateValue();

private:
    double minValue;                //最小值
    double maxValue;                //最大值
    double value;                   //目标电量
    double alarmValue;              //电池电量警戒值

public:
    double getMinValue()            const;
    double getMaxValue()            const;
    double getValue()               const;
    double getAlarmValue()          const;

protected:
    void paintEvent(QPaintEvent *);
    void drawBorder(QPainter *painter);
    void drawBg(QPainter *painter);
    void drawHead(QPainter *painter);
};

3、编译插件

  编译运行,可以看到生成的dll文件和lib文件,我们要使用release版本的库文件,如下:
在这里插入图片描述

4、拖拽使用

(1)在designer.exe中直接拖拽

  将mybatteryplugin.dll文件,拷贝到C:\Qt\Qt5.6.2\5.6\msvc2015\plugins\designer目录下,如下:
在这里插入图片描述
  双击运行designer.exe,就可以看到自定义的插件,如下:
请添加图片描述

(2)在Qt Creator的设计师中直接拖拽

  按照上述位置拷贝,只能单独运行designer.exe时才能看到自定义控件,在Qt Creator中的设计师里面并没有看到该控件,此时,需要将mybatteryplugin.dll文件拷贝到C:\Qt\Qt5.6.2\Tools\QtCreator\bin\plugins\designer目录下,如下:
在这里插入图片描述
  重新打开Qt Creator,打开设计师,并没有发现该控件,如下:
在这里插入图片描述
  通过工具栏菜单,查看该插件,发现插件加载失败,如下:
在这里插入图片描述
在这里插入图片描述

  这是因为电池插件是MSVC2015编译的,与Qt Creator版本并不一致,如下:
在这里插入图片描述

在这里插入图片描述
  所以,我们想要在Qt Creator中的设计师中直接拖拽该插件,一定要确保编译插件的版本和Qt Creator的版本一致。

5、在项目中正常使用

  如果已经实现了在Qt Creator设计师中的正常拖拽,我们可以按照库文件使用的方式,使用我们自定义的插件。
  使用Qt Creator新建demo工程,将mybatteryplugin.dll、mybatteryplugin.lib库文件和mybattery.h头文件,放到工程源码文件夹,添加外部库,如下:
在这里插入图片描述
在这里插入图片描述
  pro文件内容,如下:
在这里插入图片描述
  以release方式,编译运行该demo,提示异常,将mybatteryplugin.dll文件拷贝到执行文件同目录即可。

  • 3
    点赞
  • 77
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
下面是一个简单的 Qt定义件的例子,实现了一个带有渐变背景色和圆角边框的按钮: ```cpp #include <QPainter> #include <QMouseEvent> #include <QColor> class CustomButton : public QWidget { Q_OBJECT public: CustomButton(QWidget *parent = nullptr) : QWidget(parent) { setFixedSize(100, 30); setMouseTracking(true); } void setText(const QString &text) { m_text = text; update(); } QString text() const { return m_text; } protected: void paintEvent(QPaintEvent *event) override { QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); // 绘制背景色 QLinearGradient gradient(0, 0, 0, height()); gradient.setColorAt(0, QColor(100, 100, 100)); gradient.setColorAt(1, QColor(150, 150, 150)); painter.setBrush(gradient); painter.drawRoundedRect(rect(), 5, 5); // 绘制文字 painter.setPen(QColor(255, 255, 255)); painter.drawText(rect().center() - QRectF(0, 0, 0, 14).center(), m_text); } void enterEvent(QEvent *event) override { // 鼠标进入件时改变背景色 m_oldBrush = palette().brush(backgroundRole()); QLinearGradient gradient(0, 0, 0, height()); gradient.setColorAt(0, QColor(150, 150, 150)); gradient.setColorAt(1, QColor(200, 200, 200)); QBrush brush(gradient); palette().setBrush(backgroundRole(), brush); update(); } void leaveEvent(QEvent *event) override { // 鼠标离开件时恢复背景色 palette().setBrush(backgroundRole(), m_oldBrush); update(); } void mousePressEvent(QMouseEvent *event) override { // 发射 clicked 信号 emit clicked(); } signals: void clicked(); private: QString m_text; QBrush m_oldBrush; }; ``` 在上面的代码中,我们继承了 QWidget 类,实现了自己的 paintEvent()、enterEvent()、leaveEvent() 和 mousePressEvent() 函数,分别用于绘制件、改变背景色、恢复背景色和响应鼠标点击事件。我们还定义了一个 clicked 信号,用于通知外部程序按钮被点击了。 这个自定义件是一个简单的按钮,但是可以通过修改代码和样式表来实现更多的功能和效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

敲代码的雪糕

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

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

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

打赏作者

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

抵扣说明:

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

余额充值