为以下设备创建自定义小工具Qt Widgets Designer
Qt Widgets Designer基于插件的架构允许用户自定义和第三方自定义 widget,就像编辑标准 Qt widget 一样。自定义 widget 的所有功能都可供Qt Widgets Designer 使用,包括 widget 属性、信号和插槽。由于Qt Widgets Designer 在表单设计过程中使用的是真实的 widget,因此自定义 widget 的外观与预览时一样。
QtDesigner 模块为您提供了在Qt Widgets Designer 中创建自定义 widget 的功能。
开始使用
要将自定义 widget 与Qt Widgets Designer 整合,您需要为该 widget 提供合适的描述和适当的项目文件。
提供界面描述
为了让Qt Widgets Designer 了解您想提供的 widget 类型,请创建QDesignerCustomWidgetInterface 的子类,描述您的 widget 公开的各种属性。这些属性大多由基类中的纯虚函数提供,因为只有插件作者才能提供这些信息。
函数 | 返回值描述 |
---|---|
name() | 提供 widget 的类的名称。 |
group() | Qt Widgets Designer widget 框中 widget 所属的组。 |
toolTip() | 用于帮助用户在Qt Widgets Designer 中识别 widget 的简短描述。 |
whatsThis() | 较长的 widget 描述,供Qt Widgets Designer 的用户使用。 |
includeFile() | 使用该 widget 的应用程序必须包含的头文件。该信息存储在 UI 文件中,uic 将使用该信息在为包含自定义 widget 的表单生成的代码中创建合适的#includes 语句。 |
icon() | 可用于在Qt Widgets Designer 的 widget 框中表示 widget 的图标。 |
isContainer() | 如果该 widget 将用于容纳子 widget,则为 true;否则为 false。 |
createWidget() | 指向自定义 widget 实例的QWidget 指针,该实例由父代提供。 注意: createWidget() 是一个工厂函数,只负责创建 widget。在 load() 返回之前,自定义 widget 的属性不可用。 |
domXml() | widget 属性的描述,如对象名称、大小提示和其他标准QWidget 属性。 |
codeTemplate() | 此函数保留给Qt Widgets Designer 在将来使用。 |
另外两个虚拟函数也可以重新实现:
initialize() | 为自定义部件设置扩展和其他功能。自定义容器扩展(参见QDesignerContainerExtension )和任务菜单扩展(参见QDesignerTaskMenuExtension )应在此函数中设置。 |
isInitialized() | 如果部件已初始化,则返回 true;否则返回 false。重新实现时通常会检查initialize() 函数是否已被调用,并返回测试结果。 |
关于domXml()
函数的说明
domXml()
函数返回一个用户界面文件片段,Qt Widgets Designer 的部件工厂使用该文件片段创建自定义部件及其适用属性。
自 Qt 4.4 起,Qt Widgets Designer 的 widget 框允许用一个完整的 UI 文件来描述一个自定义 widget。可使用<ui>
标签加载 UI 文件。指定 <ui> 标签可添加 <customwidget> 元素,该元素包含自定义 widget 的附加信息。如果不需要额外信息,<widget>
标签就足够了
如果自定义 widget 不提供合理的尺寸提示,则有必要在子类中的domXml()
函数返回的字符串中指定默认几何尺寸。例如,自定义widget 插件示例提供的AnalogClockPlugin
按以下方式定义了默认 widgetgeometry:
... R"( <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>100</width> <height>100</height> </rect> </property> ") ...
domXml()
函数的另一个特点是,如果返回空字符串,则不会在Qt Widgets Designer 的窗口小部件框中安装窗口小部件。不过,表单中的其他窗口小部件仍可使用该窗口小部件。该功能用于隐藏用户不应明确创建但其他部件需要的部件。
完整的自定义 widget 规范如下
<ui language="c++"> displayname="MyWidget"> <widget class="widgets::MyWidget" name="mywidget"/> <customwidgets> <customwidget> <class>widgets::MyWidget</class> <addpagemethod>addPage</addpagemethod> <propertyspecifications> <stringpropertyspecification name="fileName" notr="true" type="singleline"/> <stringpropertyspecification name="text" type="richtext"/> <tooltip name="text">Explanatory text to be shown in Property Editor</tooltip> </propertyspecifications> </customwidget> </customwidgets> </ui>
<ui>
标签的属性:
属性 | 存在 | 值 | 评论 |
---|---|---|---|
language | 可选 | "c++, jambi | 此属性指定自定义 widget 使用的语言。它主要用于防止 C++ 插件出现在 Qt Jambi 中。 |
displayname | 可选的 | 类名 | 该属性的值显示在 widget 框中,可用于剥离命名空间。 |
<addpagemethod>
标签告诉Qt Widgets Designer 和uic应该使用哪种方法向容器部件添加页面。这适用于需要调用特定方法来添加子节点,而不是通过传递父节点来添加子节点的容器部件。这尤其适用于那些不是Qt Widgets Designer 中提供的容器的子类,而是基于当前页面概念的容器。此外,您还需要为它们提供容器扩展。
<propertyspecifications>
元素可以包含一系列属性元信息。
标签<tooltip>
可用于指定悬停在属性上时在属性编辑器中显示的工具提示。属性名称在属性name
中给出,元素文本就是工具提示。此功能在 Qt 5.6 中添加。
对于字符串类型的属性,可以使用<stringpropertyspecification>
标签。该标签具有以下属性:
属性 | 存在 | 值 | 注释 |
---|---|---|---|
name | 必填 | 属性名称 | |
type | 必填 | 见下表 | 属性值决定属性编辑器如何处理它们。 |
notr | 可选 | "true"、"false | 如果属性值为 "true",则不翻译该值。 |
type
属性的值:
值 | 类型 |
---|---|
"richtext" | 富文本。 |
"multiline" | 多行纯文本。 |
"singleline" | 单行纯文本。 |
"stylesheet" | CSS 样式表。 |
"objectname" | 对象名称(有限的有效字符集)。 |
"url" | URL 文件名。 |
插件要求
为使插件能在所有平台上正常工作,您需要确保它们导出Qt Widgets Designer 所需的符号。
首先,必须导出插件类,插件才能被Qt Widgets Designer 加载。请使用Q_PLUGIN_METADATA() 宏来实现这一点。此外,还必须使用QDESIGNER_WIDGET_EXPORT 宏来定义插件中的每个自定义部件类,以便Qt Widgets Designer 将其实例化。
创建行为良好的小工具
一些自定义部件具有特殊的用户界面功能,这可能会使它们的行为与Qt Widgets Designer 中的许多标准部件不同。具体来说,如果自定义部件因调用QWidget::grabKeyboard() 而抓取键盘,那么Qt Widgets Designer 的运行将受到影响。
要在Qt Widgets Designer 中赋予自定义部件特殊行为,请提供初始化()函数的实现,以便为Qt Widgets Designer 的特定行为配置部件构建过程。该函数将在调用 createWidget() 之前首次调用,或许可以设置一个内部标志,以便以后Qt Widgets Designer 调用插件的 createWidget() 函数时进行测试。
构建和安装插件
一个简单的插件
自定义小部件插件演示了一个简单的Qt Widgets Designer 插件。
插件的项目文件必须指定自定义部件和插件接口的头文件和源文件。通常情况下,该文件只需指定插件项目将以库的形式构建,但要为Qt Widgets Designer 提供特定的插件支持。对于CMake
,可通过以下声明完成:
find_package(Qt6 REQUIRED COMPONENTS Core Gui UiPlugin Widgets) qt_add_plugin(customwidgetplugin) target_sources(customwidgetplugin PRIVATE analogclock.cpp analogclock.h customwidgetplugin.cpp customwidgetplugin.h ) target_link_libraries(customwidgetplugin PUBLIC Qt::Core Qt::Gui Qt::UiPlugin Qt::Widgets )
链接库列表指定Qt::UiPlugin
。这表明插件只使用QDesignerCustomWidgetInterface 和QDesignerCustomWidgetCollectionInterface 的抽象接口,而与Qt Widgets Designer 库没有链接。访问Qt Widgets Designer 的其他有链接的接口时,应使用Designer
代替;这样可确保插件动态链接到Qt Widgets Designer 库,并在运行时依赖于这些库。
此外,还有必要确保该插件与其他Qt Widgets Designer widget 插件一起安装:
set(INSTALL_EXAMPLEDIR "${QT6_INSTALL_PREFIX}/${QT6_INSTALL_PLUGINS}/designer") install(TARGETS customwidgetplugin RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" )
对于qmake
:
CONFIG += plugin TEMPLATE = lib HEADERS = analogclock.h \ customwidgetplugin.h SOURCES = analogclock.cpp \ customwidgetplugin.cpp OTHER_FILES += analogclock.json
QT
变量包含关键字uiplugin
,相当于Qt::UiPlugin
库。
此外,还需确保该插件与其他Qt Widgets Designer widget 插件一起安装:
target.path = $$[QT_INSTALL_PLUGINS]/designer INSTALLS += target
$[QT_INSTALL_PLUGINS]
变量是已安装 Qt 插件位置的占位符。您可以在运行应用程序前设置QT_PLUGIN_PATH
环境变量,配置Qt Widgets Designer 在其他位置查找插件。
注意: Qt Widgets Designer 将在提供的每个路径中查找designer
子目录。
有关 Qt 应用程序自定义库和插件路径的更多信息,请参阅QCoreApplication::libraryPaths() 。
如果插件是在与Qt Widgets Designer 不兼容的模式下构建的,它们将不会被加载和安装。有关插件的更多信息,请参阅Plugins HOWTO文档。
分割插件
上述简单方法会带来一个问题,尤其是在使用Qt Widgets Designer 的其他具有链接功能的接口时:使用自定义 widget 的应用程序将依赖于Qt Widgets Designer 头文件和库。在现实世界中,我们并不希望出现这种情况。
下文将介绍如何解决这一问题。
将 Widget 链接到应用程序
使用qmake
时,可通过创建.pri
文件,在应用程序和Qt Widgets Designer 之间共享自定义 Widget 的源文件和头文件:
INCLUDEPATH += $$PWD HEADERS += $$PWD/analogclock.h SOURCES += $$PWD/analogclock.cpp
然后,插件和应用程序的.pro
文件将包含该文件:
include(customwidget.pri)
使用CMake
时,同样可以将 widget 的源文件添加到应用程序项目中。
使用库共享小工具
另一种方法是将 Widget 放入与Qt Widgets Designer 插件和应用程序链接的库中。建议使用静态库,以免在运行时出现定位问题。
有关共享库,请参阅创建共享库。
通过 QUiLoader 使用插件
向QUiLoader 添加自定义窗口小部件的首选方法是对QUiLoader::createWidget() 进行子类化。
不过,也可以使用Qt Widgets Designer 自定义 widget 插件(参见QUiLoader::pluginPaths() 和相关函数)。为避免在目标设备上部署Qt Widgets Designer 库,这些插件不应与Qt Widgets Designer 库有任何链接(QT = uiplugin
,请参阅为Qt Widgets Designer#BuildingandInstallingthePlugin创建自定义部件)。
相关示例
有关在Qt Widgets Designer 中使用自定义部件的更多信息,请参阅自定义部件插件和任务菜单扩展示例,了解在Qt Widgets Designer 中使用自定义部件的更多信息。此外,您还可以使用QDesignerCustomWidgetCollectionInterface 类将多个自定义 widget 组合到一个库中。
© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.