在上一篇博文【VS+Qt项目开发】(五)解决方案与项目模块的属性配置中,我介绍了一些基本配置。接下来我介绍一下我在项目中创建使用QT自定义插件的过程。
项目代码已经上传,点击项目源码下载
先看一下我们这个项目的总体结构,已有主项目和静态库项目,我们要生成插件项目并使用。
1.1 创建Qt插件
解决方案右键——>添加——>新建项目——>Qt
我们新建一个名为AnalyzeWidget的Qt插件
选择父类为QWidget
1.2 增加项目的平台属性
新建的项目,属性中【平台】部分可能只有Win32,我们需要新建一个x64的平台,便于后面适应平台
当前只有Win32平台
点击【配置管理器】——>点击AnalyzeWidget的平台,选择【新建】——>点击新建平台,下拉框中选择【x64】——>确定
出现了x64平台,现在选择【所有平台】
1.3 添加输出文件夹
仔细看上面属性页的【输出目录】和【中间目录】,这个路径我们需要修改。按照我们在之前博文【VS+Qt项目开发】(三)解决方案与项目文档架构设计中1.2小节所示,我们需要在当前项目路径下增加Output和Output\TempFile两个文件夹
1.4 修改项目输出路径
【输出目录】:$(SolutionDir)$(ProjectName)\Output\$(Platform)\$(Configuration)\
【中间目录】:$(SolutionDir)$(ProjectName)\Output\TempFile\$(Platform)\$(Configuration)\
1.5 修改项目配置属性
现在我们的项目的【配置类型】是应用程序(.exe),我们要修改其为动态库(.dll),扩展名也改为.dll
【链接器】——>常规——>输出文件——>后缀改为dll
1.6 添加静态库依赖
我们的插件很可能也会使用到我们的静态库中的代码(第三方代码库),如果你的项目不使用可以忽略。
关于静态库的具体创建和使用,参见另一篇博文【VS+Qt项目开发】在VS2015中导入/创建静态库并使用静态库
我们需要在属性中增加静态库中头文件的路径,因为插件只需要在编码期间依赖。
附加包含目录:$(SolutionDir)Common\Common_VS2015\include;(这是我的项目设置的路径)
总算开始编码了~~
2.1 提供了一个接口描述
为了通知Qt Designer想要提供窗口部件的类型,则需要创建一个QDesignerCustomWidgetInterface的子类,其中描述了部件暴露的各种属性,其大多数是由基类中的纯虚函数提供的,因为只有插件的作者可以提供这方面的信息。
编号 |
函数 |
返回值描述 |
1 |
name() |
提供了插件的类名称 |
2 |
group() |
该控件所属的组中的Qt Designer的小工具盒 |
3 |
toolTip() |
一个简短的说明,以帮助用户识别Qt Designer中的部件 |
4 |
whatsThis() |
为Qt Designer用户设计的部件一个较长的描述 |
5 |
includeFile() |
头文件必须包含在使用该插件的应用程序的。此信息存储在UI文件中,并将由UIC创建用于包含自定义插件形式的代码合适的#includes语句。 |
6 |
icon() |
Qt Designer的插件箱中小窗口的图标 |
7 |
isContainer() |
true表示部件将用来保存子部件,否则为false |
8 9 10 |
createWidget() domXml() codeTemplate() |
一个指向自定义窗口小部件的QWidget指针实例,构建了所提供的父母。 注:createWidget()是一个工厂方法,只负责创建小部件的功能。自定义窗口小部件的属性将不可用,直到load()返回。 描述了部件的属性,例如:对象名称、大小提示,以及其它标准的QWidget属性的描述。 这个函数是预留给Qt Designer将来使用的 |
其它两个虚函数也可以重新实现
编号 | 函数 | 返回值描述 |
11 | initialize() | 设置了自定义窗口部件扩展等功能。自定义容器扩展(见QDesignerContainerExtension)和任务菜单扩展(见QDesignerTaskMenuExtension)应在此函数中设置。 |
12 | isInitialized() | 如果该部件已被初始化,则返回true;否则返回false。重新实现通常检查initialize()函数是否已被调用,并返回本次测试的结果。 |
新建头文件AnalyzeWidgetPulgin.h
#ifndef ANALYZEWIDGETPLUGIN_H
#define ANALYZEWIDGETPLUGIN_H
#include
#include
#include
#define AnalyzeWidgetPlugin_iid "org.myPlugins.AnalyzeWidgetPluginFactoryInterface"
class AnalyzeWidgetPlugin : public QObject, public QDesignerCustomWidgetInterface
{
Q_OBJECT
Q_INTERFACES(QDesignerCustomWidgetInterface)
Q_PLUGIN_METADATA(IID AnalyzeWidgetPlugin_iid FILE "analyzewidgetplugin.json")
public:
AnalyzeWidgetPlugin(QObject *parent = 0);
//true表示部件将用来保存子部件,否则为false
bool isContainer() const;
bool isInitialized() const;
//Qt Designer的插件箱中小窗口的图标
QIcon icon() const;
//描述了部件的属性,例如:对象名称、大小提示,以及其它标准的QWidget属性的描述。
QString domXml() const;
//该控件所属的组中的Qt Designer的小工具盒
QString group() const;
//头文件必须包含在使用该插件的应用程序的。此信息存储在UI文件中,并将由UIC创建用于包含自定义插件形式的代码合适的#includes语句。
QString includeFile() const;
//提供了插件的类名称
QString name() const;
//一个简短的说明,以帮助用户识别Qt Designer中的部件
QString toolTip() const;
//为Qt Designer用户设计的部件一个较长的描述
QString whatsThis() const;
//一个指向自定义窗口小部件的QWidget指针实例,构建了所提供的父母
QWidget *createWidget(QWidget *parent);
void initialize(QDesignerFormEditorInterface *core);
private:
bool initialized;
};
#endif // ANALYZEWIDGETPLUGIN_H
创建Cpp文件AnalyzeWidgetPlugin.cpp
#include "analyzewidget.h"
#include
#include "analyzewidgetplugin.h"
AnalyzeWidgetPlugin::AnalyzeWidgetPlugin(QObject *parent)
: QObject(parent)
{
initialized = false;
}
void AnalyzeWidgetPlugin::initialize(QDesignerFormEditorInterface *)
{
if (initialized)
return;
initialized = true;
}
bool AnalyzeWidgetPlugin::isInitialized() const
{
return initialized;
}
QWidget *AnalyzeWidgetPlugin::createWidget(QWidget *parent)
{
return new AnalyzeWidget(parent);
}
QString AnalyzeWidgetPlugin::name() const
{
return "AnalyzeWidget";
}
QString AnalyzeWidgetPlugin::group() const
{
return "My Plugins";
}
QIcon AnalyzeWidgetPlugin::icon() const
{
return QIcon();
}
QString AnalyzeWidgetPlugin::toolTip() const
{
return QString();
}
QString AnalyzeWidgetPlugin::whatsThis() const
{
return QString();
}
bool AnalyzeWidgetPlugin::isContainer() const
{
return false;
}
QString AnalyzeWidgetPlugin::domXml() const
{
return "\n"
" \n"
" \n"
" 0 \n"
" 0 \n"
" 100 \n"
" 100 \n"
" \n"
" \n"
" \n";
}
QString AnalyzeWidgetPlugin::includeFile() const
{
return "analyzewidget.h";
}
2.2 添加json文件
头文件AnalyzeWidgetPulgin.h中有如下代码
Q_PLUGIN_METADATA(IID AnalyzeWidgetPlugin_iid FILE "analyzewidgetplugin.json")
analyzewidgetplugin.json 里面就一句话
{ "keys" : ["AnalyzeWidget"]}
2.3 插件具体内容编码
该部分的代码我就不贴出来啦,看一下插件的UI。项目的具体代码已经上传,点击项目源码下载
3.1 编译UI文件
刚创建的UI文件需要先编译一下才可以
3.2 编译插件
AnalyzeWidget项目文件上右键——>生成
生成三个文件,后缀分别为.dll/.exp/.lib
4.1 复制编译文件
将得到的后缀为dll与lib的文件复制到Qt安装目录下的
C:\Qt\Qt5.8.0_x86\5.8\msvc2015\plugins\designer
前面的路径因人而异,不过最后都是plugins下的designer文件夹
4.2 复制相关文件
(1)将AnalyzeWidget文件夹下的两个文件AnalyzeWidget.cpp/AnalyzeWidget.h拷贝到主项目下
复制到主项目MySolution下(我们在主项目中会用到)
(2)将AnalyzeWidget中生成的文件GeneratedFile/ui_AnalyzeWidget.h复制到主项目的生成目录下
复制到主项目MySolution/GeneratedFiles下
4.3 在主项目中添加文件
添加——>现有项
至此,我们所有准备工作就算做好了~~在我们的UI文件中使用吧~
双击MySolution.ui,你可以在左下角看到My Plugins,这个栏目名字就是我们2.1节中提到的group()方法返回的值。
直接将里面的AnalyzeWidget插件拖到界面就可以使用啦~
具体的信息可以点击【帮助】——>【关于插件】查看
调用成功~
大功告成!
点击阅读下一篇【VS+Qt项目开发】(七)让Qt控件随窗口自适应变化大小
欢迎到我的GitHub主页下载项目源码~