二十一、Qt之自定义 Qt Designer 插件

一:检查 Qt Creator 编译器版本

单击 Qt Creator 的 “帮助”–>“关于 Qt Creator”菜单,出现的对话框会显示 Qt Creator 的版本信息和使用的编译器信息。Qt5.9的 Qt Creator 是基于 MSVC2015 32bit 编译器编译的。

二:配置 MSVC2015 32bit 编译器

参见 Qt5 + msvc2015编译器 环境配置 (不安装VS)

三:自定义 Qt Designer 插件

1、设置插件项目名称和保存路径,本案例设置项目名称为 QwBatteryPlugin

2、选择项目编译器,保持和 Qt Creator 编译器版本一致,本案例就是 MSVC2015 32bit 编译器

3、设置自定义 QWidget 类的名称

本案例名称为 QwBattery
唯一需要注意的就是:

  • 在 Sources 选项卡中,设置 Icon:自定义 QWidget 显示图标
  • 在 Description 选项卡中设置分组(Group):分组(Group)是自定义组件在组件面板里的分组名称,这里设置为 My Widget

4、显示和设置插件、资源文件名称

一般用默认生成的即可。

5、完成设置,生成项目

6、组件类 QWidget 的定义

qwbattery.h

#ifndef QWBATTERY_H
#define QWBATTERY_H

#include <QtUiPlugin/QDesignerExportWidget>
#include <QWidget>
#include <QColor>
#include <QRect>
#include <QPainter>
/**
 * @brief QDESIGNER_WIDGET_EXPORT 宏:用于将自定义组件类从插件导出给 Qt Designer 使用,
 *        必须在类名称前使用此宏
 */
class QDESIGNER_WIDGET_EXPORT QwBattery : public QWidget
{
    Q_OBJECT
	//这是控件可编辑的属性:powerLevel对应类中一个私有属性 getPowerLevel、setPowerLevel、powerLevelChanged对应类中的方法
    Q_PROPERTY(int powerLevel READ getPowerLevel WRITE setPowerLevel
               NOTIFY powerLevelChanged DESIGNABLE true)

public:
    QwBattery(QWidget *parent = 0);
    void setPowerLevel(int pow);
    int getPowerLevel();
    void setWarnLevel(int warn);
    int getWarnLevel();
    //缺省大小
    QSize sizeHint();
private:
    QColor colorBack = Qt::white;
    QColor colorBorder = Qt::black;
    QColor colorPower = Qt::green;
    QColor colorWarning = Qt::red;
    int powerLevel = 60;
    int warnLevel = 20;
protected:
    void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE;
signals:
    void powerLevelChanged(int);
};

#endif

qwbattery.cpp

#include "qwbattery.h"

QwBattery::QwBattery(QWidget *parent) :
    QWidget(parent)
{
}

void QwBattery::setPowerLevel(int pow)
{
    powerLevel = pow;
    emit powerLevelChanged(pow);
    repaint();
}

int QwBattery::getPowerLevel()
{
    return powerLevel;
}

void QwBattery::setWarnLevel(int warn)
{
    warnLevel = warn;
    repaint();
}

int QwBattery::getWarnLevel()
{
    return warnLevel;
}

QSize QwBattery::sizeHint()
{
    int height = this->height();
    int width = height * 12 /5;
    QSize size(width, height);
    return size;
}

void QwBattery::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event);
    QPainter painter(this);
    QRect rect(0, 0, width(), height());
    painter.setViewport(rect);
    painter.setWindow(0, 0, 120, 50);
    painter.setRenderHint(QPainter::Antialiasing);
    painter.setRenderHint(QPainter::TextAntialiasing);

    QPen pen;
    pen.setWidth(2);
    pen.setColor(colorBorder);
    pen.setStyle(Qt::SolidLine);
    pen.setCapStyle(Qt::FlatCap);
    pen.setJoinStyle(Qt::BevelJoin);
    painter.setPen(pen);
    QBrush brush;
    brush.setColor(colorBack);
    brush.setStyle(Qt::SolidPattern);
    painter.setBrush(brush);
    rect.setRect(1, 1, 109, 48);
    painter.drawRect(rect);
    brush.setColor(colorBorder);
    painter.setBrush(brush);
    rect.setRect(110, 15, 10, 20);
    painter.drawRect(rect);

    if (powerLevel > warnLevel)
    {
        brush.setColor(colorPower);
        pen.setColor(colorPower);
    }
    else
    {
        brush.setColor(colorWarning);
        pen.setColor(colorWarning);
    }
    painter.setBrush(brush);
    painter.setPen(pen);

    if (powerLevel > 0)
    {
        rect.setRect(5, 5, powerLevel, 40);
        painter.drawRect(rect);
    }

    QFontMetrics textSize(this->font());
    QString powerStr = QString::asprintf("%d%%", powerLevel);
    QRect textRect = textSize.boundingRect(powerStr);
    painter.setFont(this->font());
    pen.setColor(colorBorder);
    painter.setPen(pen);
    painter.drawText(55 - textRect.width() / 2, 23 + textRect.height() / 2, powerStr);
}

四、插件的编译与安装

插件在 Release 模式下编译,生成文件:qwbatteryplugin.dll 和 qwbatteryplugin.lib,插件在 Debug 模式下编译,生成文件:qwbatteryplugind.dll 和 qwbatteryplugind.lib,两个的区别就是 Debug 编译生成的文件名末尾多一个 “d” 字母。将 qwbatteryplugin.dll 和 qwbatteryplugind.dll 动态链接库文件复制到下面两个目录:

D:\Qt\Qt5.9.0\Tools\QtCreator\bin\plugins\designer
D:\Qt\Qt5.9.0\5.9\msvc2015\plugins\designer

重启 Qt Creator,使用 UI 设计器设计窗口时,在左侧的组件面板会看到增加一个 My Widget 分组,分组里面有一个组件 QwBattery:
在这里插入图片描述

五、使用自定义插件

1、新建一个项目 BatteryUser,设计界面如下:
在这里插入图片描述
编辑 滑块控件和电池控件的槽函数:

void MyWidget::on_qwBattery_powerLevelChanged(int arg1)
{
    QString str = QString::asprintf("当前电量:%d %%", arg1);
    ui->labelInfo->setText(str);
}

void MyWidget::on_horizontalSlider_valueChanged(int value)
{
    ui->battery->setPowerLevel(value);
}

2、在项目的源文件目录下创建一个 include 子目录,将 QwBattery 类定义的头文件 qwbattery.h 、插件的 debug 和 release 两种模式编译生成的库文件 qwbatteryplugind.lib 和 qwbatteryplugin.lib 复制到此目录下,项目在编译链接时需要此头文件和库文件。

3、导入库文件

方式一:引导方式
右击项目,在弹出的菜单中选择 “添加库…” ,选择库类型时,选择 外部库“External Library”;选择库文件位置时,就把 include 文件夹下的 qwbatteryplugin.lib 选中即可,会自动填充 “Include path”编辑框,选择 windows 平台,连接方式选择 Dynamic ,勾选下方 Add “d” suffix for debug version,表示在 debug 版本的库名称后面添加一个字母 “d”,以便编译器自动区分 release 和 debug 版本的库文件。

方式二:手动代码导入
修改项目文件 BatteryUser.pro,添加:

#设置添加的库文件,会判断当前项目时以 debug 还是 release 模式编译
win32:CONFIG(release, debug|release): LIBS += -L$$PWD/include/ -lqwbatteryplugin
else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/include/ -lqwbatteryplugind
#头文件目录
INCLUDEPATH += $$PWD/include
#项目依赖目录
DEPENDPATH += $$PWD/include

4、运行项目
此时可正常编译,但是无法正常运行,一旦运行,会直接崩溃,且无报错信息。
(1)第一步:编译
在 debug 和 release 两种模式下分别编译。
(2)第二步:复制插件的 dll 文件
将插件在 debug 和 release 两种模式下编译生成的 qwbatteryplugin.dll 和 qwbatteryplugind.dll 动态链接库文件分别复制到项目编译的两个文件夹下:

E:\Qt_Demo\build-BatteryUser-Desktop_Qt_5_9_0_MSVC2015_32bit-Debug\debug
E:\Qt_Demo\build-BatteryUser-Desktop_Qt_5_9_0_MSVC2015_32bit-Release\release

(3)第三步:运行
在这里插入图片描述

六、遇到的问题及解决办法

二十三、Qt5.9 + msvc2015编译器 环境配置 (不安装VS)

二十四、Qt lnk1158 无法运行rc.exe 解决方法

二十六、Qt之使用 MSVC编译器输出中文乱码的问题

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值