如何创建 Qt 插件?
如何创建 Qt 插件?
简单三部曲
- 定义接口类或接口基类并使用
Q_DECLARE_INTERFACE宏进行声明 - 所有的插件都需要继承该基类并继承 QObject(不带界面插件) or QWidget(带界面插件)
- 在插件类中添加
Q_PLUGIN_METADATA导出元数据,使用Q_INTERFACES指定继承基类(该基类需要使用Q_DECLARE_INTERFACE声明过)
如何生成?
示例
*.pro 文件内容如下
# 插件依赖模块
QT += core gui widgets
# 生成目标文件名称
TARGET = FlowWidget
TEMPLATE = lib
CONFIG += plugin
# 插件输出目录
DESTDIR = $$[QT_INSTALL_PLUGINS]/generic
DEFINES += QT_DEPRECATED_WARNINGS
SOURCES += \
flowWidget.cpp
HEADERS += \
flowWidget.h
DISTFILES += FlowWidget.json
include($$PWD/interface/interface.pri)
interface.pri 内容如下:
SOURCES += \
HEADERS += \
$$PWD/flowInterface.h
INCLUDEPATH += $$PWD
纯接口类定义如下:
#include <QtPlugin>
class QImage;
class QString;
class QWidget;
class FlowInterface
{
public:
FlowInterface() {}
virtual ~FlowInterface() {}
virtual void process() = 0;
/*!
属性页
*/
virtual QWidget *propertyPage() = 0;
};
#define FlowInterface_iid "com.xiongwei.cheung.FlowInterface"
Q_DECLARE_INTERFACE(FlowInterface, FlowInterface_iid)
注意:在插件类中我们需要实现接口中定义的纯虚函数
插件定义分为带界面和不带界面两种,采用多重继承的方式分别继承 QWidget 或 QObject 即可.
- 带界面插件定义如下:
class FlowWidget : public QWidget , FlowInterface
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "com.xiongwei.cheung.FlowWidget" FILE "FlowWidget.json")
Q_INTERFACES(FlowInterface)
public:
explicit FlowWidget(QWidget *parent = nullptr);
void process();
QWidget *propertyPage();
signals:
public slots:
private:
};
FlowWidget::FlowWidget(QWidget *parent) : QWidget(parent)
{
}
void FlowWidget::process()
{
// to do something
}
QWidget *FlowWidget::propertyPage()
{
return this;
}
FlowWidget.json 文件是可选的,可通过该文件实现密钥插件
{
"Keys" : [ "FlowWidget" ]
}
- 不带界面插件定义如下:
class FlowObject : public QObject , FlowInterface
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "com.xiongwei.cheung.FlowObject")
Q_INTERFACES(FlowInterface)
public:
explicit FlowObject(QObject *parent = nullptr);
void process();
QWidget *propertyPage();
signals:
public slots:
private:
};
FlowObject::FlowObject(QObject *parent) : QObject(parent)
{
}
void FlowObject::process()
{
// to do something
}
QWidget *FlowObject::propertyPage()
{
return nullptr;
}
如何使用?
在 main.cpp 文件中添加插件加载路径
QCoreApplication::applicationDirPath().append("\generic");
在工程文件中包含插件接口基类文件 flowInterface.h
#include <QPluginLoader>
#include "flowInterface.h"
void load()
{
// 添加一个枚举目录所有动态库文件即可加载所有插件
QPluginLoader pluginLoader("FlowWidget.dll");
// 打印插件元数据,即 json 文件内容中的键值数据
qDebug() << pluginLoader.metaData();
// 加载该插件
QObject *plugin = pluginLoader.instance();
if (plugin) {
// 转换成接口基类指针
FlowInterface *p = qobject_cast<FlowInterface *>(plugin);
if (p){
// 显示界面
p->propertyPage()->show();
}
}
}
注意一个插件类中只能存在一个 Q_PLUGIN_METADATA 宏,使用该宏会导出 qt_plugin_instance 和 qt_plugin_query_metadata 俩个函数。
显然如果使用 2 次 Q_PLUGIN_METADATA 宏会导致函数重定义.
实际上如果向导出多个插件的可以使用 QGenericPlugin 的手法根据 keys and `` 创建不同的对象.
如何创建 Qt 插件?的更多相关文章
- [Qt Creator 快速入门] 第9章 国际化、帮助系统和Qt插件
一.国际化 国际化的英文表述为Internationalization,通常简写为I18N(首尾字母加中间的字符数),一个应用程序的国际化就是使该应用程序可以让其他国家的用户使用的过程. Qt支持现在 ...
- [Qt插件]-03创建Qt Designer自定义部件
如何创建自定义部件并添加到Qt Designer来爽快的拖动部件可视化界面设计? Qt Designer基于插件的架构使得它可以使用用户设计或者第三方提供的自定义部件,就像使用标准的Qt部件一样. ...
- [Qt插件]-02创建应用程序插件(插件化开发的一种思路)
本篇是学习Qt Creator快速入门,插件开发的笔记 分为两部分 创建插件 使用插件的应用程序(测试插件) 插件是被使用的应用程序加载使用的. 是使用插件的应用程序定义接口,插件按照接口来实 ...
- VS2013中使用QT插件后每次重新编译问题
环境 系统:win7 64位旗舰版 软件:VS2013.QT5.5.1-32位.Qt5 Visual Studio Add-in1.2.4 概述 使用QT Visual Studio插件打开pro项目 ...
- VS2017上在线和离线安装Qt插件(在线安装)
版权声明:如需转载,请告知博主并声明出处 https://blog.csdn.net/CLinuxF/article/details/88816436文章目录前言在线安装离线安装(推荐)前言很多朋友喜 ...
- 【Win10+eclipse+MinGW+QT安装教程】已有eclipse环境下配置QT插件出错详解
(纪念一下装了一整天濒临绝望的自己[/doge]) (以下所有下载项一律使用32位) step1:下载安装eclipse.适配的jdk.MinGW和QT 1.下载32位eclipse for c++以 ...
- 设置qt插件路径
1.在Qt中使用 WebKit 浏览器核心 使用 QtWebKit 需要在工程文件(*.pro)中加入: QT +=webkitQT += network 2.QtWebKit的flash支持 QtW ...
- Qt 插件学习(一)
插件是什么 注意:这儿暂时不考虑静态插件(潜意识中总觉得它根本就不算插件). 插件是一个动态库(共享库).动态库是一个独立的文件中的独立模块,可被多个程序访问. 先看动态库的两种用法 1. 程序链接时 ...
- [Qt插件]-01Qt插件&&提升部件(自定义控件)
本篇的文档为:How to Create Qt Plugins https://doc.qt.io/qt-5/plugins-howto.html 前言 Qt插件(Qt Plugin)就是一个共享 ...
随机推荐
- c# Winform 调用可执行 exe 文件
c#是一个写windows桌面小工具的好东西,但有个时候,我们需要在 winform 程序中调用其他的 exe 文件,那么该如何实现呢? 如果只是拉起一个 exe 文件,可以参考如下方法实现: str ...
- 网络基础-IP地址
- 终于读完了《Essential C++》
先说这本书的优点吧 真的是一本非常好的书 不拘泥于非常具体的语法点 读这本书,可以体会到面向对象的魅力所在. 缺点就是这本书不太适合入门,当初也不知道是谁推荐我入门看这本书的. 想要大致能看懂这本书, ...
- Qt 倒计时验证码按钮效果
本来还想继承QTimer跟QPushButton去实现,后来发现可以使用两个QTimer来实现: 验证码倒计时间:(60s) 封装到widget类里: 需要这几个数据:Button,TimerA,Ti ...
- cmd优化
cmd很方便,很简约,但是看久了也会视觉疲劳 因此我们来优化一下cmd 原博文是我的一位同学写的,链接如下:https://www.cnblogs.com/ljsh/p/10877715.html 打 ...
- Redis之数据类型
一.概念: Redis:一个开源.支持网络.基于内存.键值对存储数据库. 特点:它可以支持多种数据类型. 二.数据类型 1)Redis String 具体说明: 一般的普通的k到v一个映射是Strin ...
- 父工程 pom版本
<!-- 集中定义依赖版本号 --> <properties> <junit.version>4.12</junit.version> <spri ...
- 算法-python
选择排序:一个列表被分为无序列表和有序列表,选择排序就是拿无序列表的第一个和后面的每一个相比较,每一趟选择出最小的一个,添加进有序列表. def select_sort(list): for i in ...
- WinForm、WPF、ASP.NET窗口生命周期
https://blog.csdn.net/s_521_h/article/details/73826928
- JAVA学习纲要
这份面试题,包含的内容了十九了模块:Java 基础.容器.多线程.反射.对象拷贝.Java Web 模块.异常.网络.设计模式.Spring/Spring MVC.Spring Boot/Spring ...