在使用Qt Designer设计窗体界面时,我们可以使用Widget Box里的窗体控件非常方便的绘制界面,比如拖进去一个按钮,一个文本编辑器等。虽然Qt Designer里的控件可以满足我们大部分的需求,但是有时候,也会产生一些特殊的需要,比如一个输入框,我们要输入的是经纬度,此时就会有两种输入方式,一种是小数形式,一种是度分秒的形式,此时只使用一个简单的LineEdit是无法满足需求的。我们设想构造这样一个输入控件,它可以支持浮点数输入,同时它还具有一个属性,更改这个属性可以使其切换为经纬度输入形式。如果我们的多个窗体上都需要输入经纬度,那么构造这样一个控件,将会非常方便。下面就以此为例,讲解一下如何创建自定义的窗体控件。
第一步:创建QtDesigner自定义控件工程
打开Qt Creator,创建一个Qt 设计师自定义控件,如下图所示:
![](https://img-blog.csdnimg.cn/img_convert/ada1cc40bff80216038e043a324453d2.bmp)
根据向导提示,建立一个新类,取名“Test"(注:首字母大写,不能全小写,不然后面会出错),一直点击”下一点“,完成工程创建。
![](https://img-blog.csdnimg.cn/img_convert/99b4f82fa9d95250a7c247888c9a27f9.png)
工程创建完毕,如下图所示:
![](https://img-blog.csdnimg.cn/img_convert/942eea42be07c8ff81118fadb489918a.png)
第二步:编辑工程代码
在新建的工程中,Test类没有ui界面文件,我们要手动添加上去,如果没有ui界面文件,工程编译也可以通过,但该控件添加到ctreator后,一打开desinger工具的时候就会直接挂掉。所以,我们可以把原先的Test类的test.c和test.h删除掉,重新添加一个Test类。
![](https://img-blog.csdnimg.cn/img_convert/15493faec7e228b5c404857b29f898dd.png)
![](https://img-blog.csdnimg.cn/img_convert/335e6c8d407cc482e790cd079052fc9f.png)
新建一个Test类,如下:
![](https://img-blog.csdnimg.cn/img_convert/50a12c04685abdc20066586ec911ed9e.png)
![](https://img-blog.csdnimg.cn/img_convert/a9cdb9f404d0dc80ab7bbad915d2accb.png)
为了减少出错机率,此时不对界面做任何动作。
在工程头文件”test.h“中添加 “#include <QtUiPlugin/QDesignerExportWidget>”,在类名前添加”QDESIGNER_WIDGET_EXPORT“宏。如下图:
![](https://img-blog.csdnimg.cn/img_convert/ca1910ec6b56d8580522e7f3929c951a.png)
第三步:编译工程
保存并选择release方式编译。先qmake一下,
![](https://img-blog.csdnimg.cn/img_convert/f59a4165bdedfc530d3f409e3a66d86a.png)
![](https://img-blog.csdnimg.cn/img_convert/572a43ffdad4e121670093dfd6699cbc.png)
点击左下角的”构建“按钮,进行编译。
![](https://img-blog.csdnimg.cn/img_convert/2dde6bd9f3e9ac57aee52edfda65aa5c.png)
编译完成。此时会生成testplugin.dll和testplugin.lib两个库。
第四步:部署插件
编译完成后,在输出目录下,找到对应的testplugin.dll和testplugin.lib两个文件。分别拷贝到QT库的designer路径下和QT的IDE工具的designer路径下。
以我本地5.7.0路径为例:(具体以个人的QT安装路径为准)
QT库的designer库路径:C:\software\GRG\Qt\Qt5.7.0\5.7\msvc2013\plugins\designer
QT库的IDE路径:C:\software\GRG\Qt\Qt5.7.0\Tools\QtCreator\bin\plugins\designer
![](https://img-blog.csdnimg.cn/img_convert/77eae1bfd7038b864e088db8a5f0ff6f.png)
![](https://img-blog.csdnimg.cn/img_convert/fcc0b5c23da8f47119bece02cbb0ca44.png)
第五步:测试使用插件
新建一个工程,在工程使用该Test自定义插件。
1、打开*.ui,在左下角会出现我们前面编译的自定义插件,如下图:
![](https://img-blog.csdnimg.cn/img_convert/26a0b7f957c6b74cb53110a1c715f65f.png)
直接拖拽到ui界面。
![](https://img-blog.csdnimg.cn/img_convert/43b1d214d49ee0919f893e8dc141b0b9.png)
2、在工程所在文件目录中,新建include文件夹,将前面的插件头文件test.h放在该include文件夹中。新建lib文件夹,将前面生成的testplugin.lib静态库放在此lib文件夹中。
![](https://img-blog.csdnimg.cn/img_convert/860e3984d90108cd83a0a9cdf6cdc39f.png)
![](https://img-blog.csdnimg.cn/img_convert/edbd5a90438b168ef4adf6a9f16ccf44.png)
![](https://img-blog.csdnimg.cn/img_convert/759d13364499e6e4c6f9c75e5c5af5bc.png)
3、打开测试工程的*.pro文件。添加相应的include路径和lib路径。
添加以下内容:
1 LIBS += $$PWD/lib/testplugin.lib
2 INCLUDEPATH += $$PWD/include
如下图:
![](https://img-blog.csdnimg.cn/img_convert/49a9084e467df93615c85e8a4f3f217f.png)
4、切换到release编译模式,点击qmake,生成相应的makefile文件。并将前面生成的testplugin.dll动态库添加到release输出目录中。如下图:
![](https://img-blog.csdnimg.cn/img_convert/048ae0d6c9ec19f794d6f315eda20671.png)
![](https://img-blog.csdnimg.cn/img_convert/99f94a7c37f128d82b30d6095c0c8e53.png)
5、点击构建,此时会生成*.exe到release输出目录。
![](https://img-blog.csdnimg.cn/img_convert/1657c532724f631765a9fd9417dd75bd.png)
此时。直接运行*.exe就可以使用该插件了。自定义插件的新建并使用到此算是OK了。
第六步:Qt自定义插件注意事项:
1:每个Qt库bin目录的designer可执行文件都是和该库同一个编译器编译的,可用,如果想要集成到Qt Creator中,则需要注意版本,一般在windows上的Qt Creator版本是MSVC的,则需要对应的Qt库也是MSVC编译的,库版本和编译器版本必须保持一致才能是顺利集成到Qt Creator的重要前提。
2:自定义控件的名称不能小写,否则拖过去的控件自动生成的默认名称和类名一样,会编译通不过。这个问题坑了我很久,造成自动生成的UI代码保存,一直没有怀疑,后面才发现自动生成的代码类名和实例名称一样,冲突导致的。
3:自定义控件类头文件引入,Qt5.7以下版本为#include <QtDesigner/QDesignerExportWidget> 以上版本为#include <QtUiPlugin/QDesignerExportWidget>
4:类名前必须加入 QDESIGNER_WIDGET_EXPORT 宏。否则集成到Qt Creator 中编译会报错。不加的话可以在设计器中加载,但是编译会报错。
5:如果将生成好的dll文件放到Qt库目录下的 plugins\designer 下,可以在 designer 中看到。放到Qt Creator下的 bin\plugins\designer 则可以集成到Qt Creator中。
6:将自定义控件的头文件、dll文件、lib(mingw编译器为.a)文件复制出来,放到include(可自己随便命名,我这里习惯用include)目录,将include目录放到项目的源码文件下,在使用了自定义控件的项目的pro文件中,增加两行 INCLUDEPATH += $$PWD/include LIBS += $$PWD/include/***.lib(mingw编译器为.a) ,这样可以正常编译,但是编译完成后不能运行,还需要将 对应自定义控件的dll文件复制到可执行文件同一目录即可,至此大功告成。
番外话:大部分文章介绍都是将对应的库文件和头文件放到Qt安装目录对应文件夹下,为什么这里要放到一个include目录,随着项目一起呢?个人是这么理解的,随项目一起,每次都可以很方便的将运行库文件复制到可执行文件同一目录,而不会忘记从Qt库对应目录找该运行库。而且发布代码的时候也可以有个很好的参考。
7:官网提供的Qt Creator版本基本上是MSVC版本,如果需要在mingw的Qt库对应的Qt Creator中集成自定义控件,需要自己用对应的Qt库编译Qt Creator源码。
个人总结:
![](https://img-blog.csdnimg.cn/img_convert/f014a22b90e4a12a57a1c95068e42d89.png)
1 如果要在qtcreator的控件界面出现自定义控件,需要按照查看的这个版本(MSVC 2017,32 bit)生成对应的库,生成release版本(只能用release版本)然后放在F:\Qt\Qt5.9.9\Tools\QtCreator\bin\plugins\designer目录中,新建qt项目,可以在qtcreator的设计面中看到对应的控件,
2 使用的时候,需要看选择的构建项目类型,如果选择msvc,release需要使用自定义控件生成的msvc,release版本库,如果选择msvc,debug,则需要使用自定义控件生成的msvc,release版本库,如果选择mingw debug构建,则需要使用自定义控件生成对应的mingw,debug库。使用时必须要将自定义控件对应的.h,静态,动态库都拷贝到对应的使用项目中,在pro文件中添加
LIBS += $$PWD/lib/libmylistviewctrlplugind.a(如果选择msvc构建项目,需要使用lib)
INCLUDEPATH += $$PWD/include
,并将对应的dll放在执行目录中。
3 如果需要在qt designer中出现对应的控件,需要将对应版本放在对应的desighner中,同样只能用release版本,F:\Qt\Qt5.9.9\5.9.9\mingw53_32\plugins\designer
/**********************************************
Qt自定义控件创建和使用
Qt中很方便的是使用各种自定义控件来分模块实现各种子功能,用于实现代码的解耦;
之前在使用Qt 5.12创建自定义控件时,出现了各种问题,多次重装QtCreator和VS,屡次失败,乃至一度放弃。话说写代码很简单,环境的配置却很难,不知道有多少人在各种开发环境的配置时,被这种挫败感打击而放弃;
不死心,从同事的实例中看到了自定义控件的有效实现,亲自实验,确实能用,写个备忘录记录一下;
一、创建自定义控件
1.首先新建项目,选择“其他项目”下的“Qt4设计师自定义控件”
2.新建一个控件类“One Plugin”
3.写入自定义控件的名称以及使用资源文件名称
将会生成一个Qt项目目录
如果想要在UI设计师界面显示自定义控件,需要将OnePlugin项目设置为Release;
OnePlugin.pro内容:
CONFIG += plugin debug_and_release
TARGET = $$qtLibraryTarget(onepluginplugin)
TEMPLATE = lib
HEADERS = onepluginplugin.h
SOURCES = onepluginplugin.cpp
RESOURCES = icons.qrc
LIBS += -L.
greaterThan(QT_MAJOR_VERSION, 4) {
QT += designer
} else {
CONFIG += designer
}
target.path = $$[QT_INSTALL_PLUGINS]/designer
INSTALLS += target
#输出dll放置在QtCreator目录路径
message($$target.path)
include(oneplugin.pri)
编译qmake
概要信息中会输出dll拷贝到QtCreator的plugins/designer目录下;
如果编译后在C:/Qt/5.15.2/msvc2019_64/plugins/designer文件夹下没有生产对于的dll;
在项目设置中“构建”Release下的“添加Build步骤”增加“Custom Process Step”
Command设置为“nmake”;Arguments设置为“install”;
清理项目,并重新构建;
可以在C:/Qt/5.15.2/msvc2019_64/plugins/designer文件夹下看到对应的dll出现;
自动生成的oneplugin.h
#ifndef ONEPLUGIN_H
#define ONEPLUGIN_H
#include <QWidget>
class OnePlugin : public QWidget
{
Q_OBJECT
public:
OnePlugin(QWidget *parent = 0);
};
#endif // ONEPLUGIN_H
需要修改为
#ifndef ONEPLUGIN_H
#define ONEPLUGIN_H
#include <QWidget>
#include <QtUiPlugin/QDesignerExportWidget>
class QDESIGNER_WIDGET_EXPORT OnePlugin : public QWidget
{
Q_OBJECT
public:
OnePlugin(QWidget *parent = 0);
};
#endif // ONEPLUGIN_H
增加了#include <QtUiPlugin/QDesignerExportWidget>和QDESIGNER_WIDGET_EXPORT
QDESIGNER_WIDGET_EXPORT的F1解释为:
This macro is used when defining custom widgets to ensure that they are correctly exported from plugins for use with Qt Designer.
至此,自定义控件算是创建完成;
将onepluginplugin.dll拷贝到Qt Creator的目录下C:\Qt\Tools\QtCreator\bin\plugins\designer,重启QtCreator;
打开ui文件后可以看到自定义控件,不要在意这里面的名字,onePluge是我瞎起的名字;
下面是使用Everything搜索的结果:
二、使用自定义控件
2.1创建测试对话框程序
在测试程序源码文件夹增加lib文件夹,将OnePlugin对应的oneplugin.h和onepluginplugin.lib拷贝到lib文件夹下;
在pro文件内增加
CONFIG += release
HEADERS += lib/
LIBS += $$PWD/lib/onepluginplugin.lib
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++11
CONFIG += release
SOURCES += \
main.cpp \
widget.cpp
HEADERS += \
widget.h
FORMS += \
widget.ui
HEADERS += lib/
LIBS += $$PWD/lib/onepluginplugin.lib
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
在对话框的头文件中增加
#include “lib/oneplugin.h”
Widget类中增加成员变量pOnePlugin;
在构造函数中pOnePlugin = new OnePlugin(this);
#include "lib/oneplugin.h"
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private:
Ui::Widget *ui;
OnePlugin* pOnePlugin;
};
编译程序,出现LNK2019:无法解析的外部符号的错误:
在这停顿了很久,翻了很多百度,发现一个有用的记录;
这里需要将使用到的oneplugin.h中的QDESIGNER_WIDGET_EXPORT删除;
还有一种情况也会出现这种问题,是lib下使用的lib编译类型与当前测试程序的编译类型不相同,重新编译oneplugin项目,将生成的lib拷贝到lib文件夹下;
编译
将dll拷贝到exe的文件夹下;
测试exe可以正常运行
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)