分享

Qt如何创建插件

 新潮看世界 2023-03-09 发布于北京

Qt提供了两种API用来创建插件:

  1. Qt扩展插件高级API,譬如:自定义数据库插件,图片格式处理插件,文本编码处理插件,自定义样式插件等。(生成的so或者lib文件需要放在Qt安装目录下)

  2. Qt应用程序插件低级API。(和动态库一样的用法)

例如:当你写了一个自定义的QStyle子类,并且由Qt应用程序动态加载它,那么可以使用高级API。

第一种,Qt扩展插件

譬如,我创建了一个MyStyle类,在里面实现了各种关于style的设置。然后我想将这个类当做插件使用,那么可以再创建一个继承QStylePlugin的的插件类,在插件类中调用MyStyle对象。

mystyleplugin.h

class MyStylePlugin : public QStylePlugin{    Q_OBJECT    Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QStyleFactoryInterface" FILE "mystyleplugin.json")public:    QStyle *create(const QString &key);};

mystyleplugin.cpp

#include "mystyleplugin.h"
QStyle *MyStylePlugin::create(const QString &key){ if (key.toLower() == "mystyle") return new MyStyle; return 0;}

另外,我们还需要创建一个mystyleplugin.json的类属性文件。文件中内容为:

{ "Keys": [ "mystyleplugin" ] }

注意,文件名和键值对中的值都得是类的小写名称。

至于其他的属性键值对,可以参考插件类的详细说明。一般只需要上面这个键值对就可以了,Qt会自动创建必要的默认属性键值对。

当我们调用的时候,代码如下:

QApplication::setStyle(QStyleFactory::create("MyStyle"));

注意,这种插件是需要放在Qt安装目录下才会生效的。

基类目录名
QAccessibleBridgePluginaccessiblebridge
QImageIOPluginimageformats
QPictureFormatPlugin (obsolete)pictureformats
QBearerEnginePluginbearer
QPlatformInputContextPluginplatforminputcontexts
QPlatformIntegrationPluginplatforms
QPlatformThemePluginplatformthemes
QPlatformPrinterSupportPluginprintsupport
QSGContextPluginscenegraph
QSqlDriverPluginsqldrivers
QIconEnginePluginiconengines
QAccessiblePluginaccessible
QStylePluginstyles

具体如下:

第二种,Qt应用程序插件(我们通常编写的大多数是这个)

这种方式使用QPluginLoader检测和加载插件

插件可以提供任意功能,不限于数据库驱动程序、图像格式、文本编解码器、样式和扩展 Qt 功能的其他类型的处理插件。

具体步骤如下:

  1. 定义一组用于与插件对话的接口(即只有纯虚函数的类)。

  2. 使用Q_DECLARE_INTERFACE () 宏来告诉 Qt 的元对象系统有关接口的信息。

  3. 在应用程序中使用QPluginLoader来加载插件。

  4. 使用qobject_cast () 来测试插件是否实现了给定的接口。

编写插件步骤:

  1. 声明一个继承自QObject和插件想要提供的接口的插件类。

  2. 使用Q_INTERFACES () 宏告诉 Qt 的元对象系统有关接口的信息。

  3. 使用Q_PLUGIN_METADATA () 宏导出插件

  4. 使用合适的文件构建插件.pro

例如,这是接口类的定义:

class FilterInterface{public:    virtual ~FilterInterface() {}
virtual QStringList filters() const = 0; virtual QImage filterImage(const QString &filter, const QImage &image, QWidget *parent) = 0;};

如下是实现接口和定义插件功能的插件类:

#include <QObject>#include <QtPlugin>#include <QStringList>#include <QImage>
#include <plugandpaint/interfaces.h>
class ExtraFiltersPlugin : public QObject, public FilterInterface{ Q_OBJECT Q_PLUGIN_METADATA(IID "org.qt-project.Qt.Examples.PlugAndPaint.FilterInterface" FILE "extrafilters.json") Q_INTERFACES(FilterInterface)
public: QStringList filters() const; QImage filterImage(const QString &filter, const QImage &image, QWidget *parent);};

一般情况下,我们编写的都是动态库类型的插件类,如果你将Qt自己源码编译成静态库,那么你就只能使用静态插件类库了。这里不再赘述了。

    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多