一、创建之前要做的事情
1.1 查看自己电脑上的 Qt Creator 用的那个编译器
说明:
以我的环境为例,只有用 MSVC2022 编译出来的“自定义 UI 控件”才能被 Qt Creator 识别,才能在 Qt Creator“设计”中拖拽使用。
不是用 MSVC2022 编译,不可以在 Qt Creator 的“设计师”中拖拽使用,但是可以使用对应编译器版本的
Designer
拖放“自定义 ui 控件”,比如我使用MinGW 13.0
的编译套件生成的“自定义 UI 控件”,就可以使用下图红框中的Designer
拖放使用
另外,想安装 MSVC 编译环境,请看:【Qt】Window环境下搭建Qt6、MSVC2022开发环境(无需提前安装Visual Studio)
二、自定义 Ui 创建步骤
- 新建项目“其它项目 --> Qt4 设计师自定义控件”
- 自定义项目“名称、创建路径”,下一步;
- 选择合适的编译套件,下一步;
前文提到过,要选择与 Qt Creator 相对应的编译环境,否则不能在 Qt Creator 中拖放使用。
- 指定自定义控件属性,按下图操作:
- 步骤 2,红框中的创建代码框架复选框,记得勾选;
- 本示例是创建一个自定义按钮,我打算在原
QPushButton
上修改,所以控件的基类我填的是QPushButton
; - “链接库” 用于复用已有编译好的控件库,没有,这里不选择。
- 插件名称、资源文件名称修改,下一步;
- 点击“完成”,创建
… 忘记截图了
三、…Plugin.h …Plugin.cpp 代码分析
先把代码贴上来:
#include "CtmPushButtonPlugin.h"
#include "CtmPushButton.h"
#include <QtPlugin>
CtmPushButtonPlugin::CtmPushButtonPlugin(QObject *parent)
: QObject(parent)
{}
void CtmPushButtonPlugin::initialize(QDesignerFormEditorInterface * /* core */)
{
if (m_initialized)
return;
// Add extension registrations, etc. here
m_initialized = true;
}
bool CtmPushButtonPlugin::isInitialized() const
{
return m_initialized;
}
QWidget *CtmPushButtonPlugin::createWidget(QWidget *parent)
{
return new CtmPushButton(parent);
}
QString CtmPushButtonPlugin::name() const
{
return QLatin1String("CtmPushButton");
}
QString CtmPushButtonPlugin::group() const
{
return QLatin1String("Buttons");
}
QIcon CtmPushButtonPlugin::icon() const
{
return QIcon();
}
QString CtmPushButtonPlugin::toolTip() const
{
return QLatin1String("");
}
QString CtmPushButtonPlugin::whatsThis() const
{
return QLatin1String("一个自定义的按钮");
}
bool CtmPushButtonPlugin::isContainer() const
{
return false;
}
QString CtmPushButtonPlugin::domXml() const
{
return QLatin1String(R"(<widget class="CtmPushButton" name="ctmPushButton">
</widget>)");
}
QString CtmPushButtonPlugin::includeFile() const
{
return QLatin1String("CtmPushButton.h");
}
以上代码是我们创建自定义 Ui 控件时, Qt Creator 自动生成的,仔细阅读这些成员函数就会发现,这些都是我们前边步骤中所设置的内容,例如:
QString CtmPushButtonPlugin::whatsThis() const
{
return QLatin1String("一个自定义的按钮");
}
再比如:
QString CtmPushButtonPlugin::group() const
{
return QLatin1String("Buttons");
}
也就是说刚才的配置是可以更改的或者说是可以再设置的。刚才我们没有设置自定义 ui 控件的图标,现在我们只需要在资源文件中添加,并且在icon()
方法中返回 icon 资源路径就好了,如下:
QIcon CtmPushButtonPlugin::icon() const
{
return QIcon(":/icon/CtmBtnIcon"); // 返回添加的 icon 资源文件
}
四、编写自定义 Ui 的代码
本文只简单举个例子,没有实现什么很复杂的样式。
- 修改
CtmPushButton.cpp
文件如下:
#include "CtmPushButton.h"
CtmPushButton::CtmPushButton(QWidget *parent) :
QPushButton("自定义按钮", parent)
{
}
- 使用
Release
模式编译运行,将生成的 DLL 库分别复制到Qt Creator 插件设计
和Qt msvc 插件设计
的路径下(复制前需要关掉你的Qt Creator
和Designer(MSVC)
):
例如我的路径如下:
我的 Qt 安装路径是:C:\Qt
,则:
Qt Creator 插件路径:C:\Qt\Tools\QtCreator\bin\plugins\designer
Qt msvc 插件路径:C:\Qt\6.9.1\msvc2022_64\plugins\designer
如下图所示:
- 然后,打开
Qt Creator
和Designer(MSVC)
就可以看到我们创建的自定义按钮了,并且还可以拖放使用,如下所示:Qt Creator
使用效果:
Designer(MSVC)
使用效果:
ps:请忽略我的垃圾录屏软件,残影好严重…
五、可能遇到的问题
5.1 分组没起作用,无论是在 Qt Creator
中还是在Designer
中。
答:看“CtmPushButtonPlugin.cpp
”文件中的“group()
”方法返回的字符串是否拼写错误,修改为如下可以正常显示在Buttons
分组中
QString CtmPushButtonPlugin::group() const
{
return QLatin1String("Buttons");
}
5.2 在代码中使用时,报“LNK2019: 无法解析的外部符号”错误
1、请检查生成DLL库文件路径、名字,是否与项目管理中添加的库文件路径、名字,是否一致;
2、注意区分是debug
版本DLL库还是release
版本库;
3、检查代码中控件类是否添加了 QDESIGNER_WIDGET_EXPORT
宏定义,以及相应头文件;Qt5.7以下版本为#include <QtDesigner/QDesignerExportWidget>
以上版本为#include <QtUiPlugin/QDesignerExportWidget>
最后,墙裂推荐这篇博文,写的很好,总结的问题也很全。
Qt编写自定义控件及插件的使用