如何建立Qt插件学习教程是本文要介绍的内容,主要是来了解QT中插件的应用,如何来建立,文中有详解,具体内容的实现来看详解。
QT提供2个API来建立插件
1、高层API扩展QT库。例如定制的数据库驱动,图像格式,字符编码,custom styles
2、底层API扩展QT应用程序
例如,如果想写自定义QStyle的子类,并让应用程序动态加载,需要使用高层API函数
因为高层API在底层API基础上构造,两者需要注意一些问题。
如果需要提供给QT Designeder插件,请参考QtDesigner模型文档
高层API
利用继承特定的基类来实现插件,需要实现其中的一些函数,并增加一个宏
QT中有不少插件的基类可供使用,继承的插件默认保存在标准插件目录的子目录下,否则Qt会找不到。
设计一个style类名为MyStyle的插件
文件mystyleplugin.h:
- class MyStylePlugin : public QStylePlugin
- {
- public:
- QStringList keys() const; //返回此插件能够使用的style名称列表。
- QStyle *create(const QString &key);//根据传入的style名称,返回style。
- };
- mystyleplugin.cpp
- #include "mystyleplugin.h"
- QStringList MyStylePlugin::keys() const
- {
- return QStringList() << "MyStyle";
- }
- QStyle *MyStylePlugin::create(const QString &key)
- {
- if (key.toLower() == "mystyle")
- return new MyStyle;
- return 0;
- }
- Q_EXPORT_PLUGIN2(pnp_mystyleplugin, MyStylePlugin)
风格实现
文件mystyle.h:
- class MyStyle : public QWindowsStyle
- {
- Q_OBJECT
- public:
- MyStyle() {};
- void polish(QPalette &palette);
- };
继承自QWindowsStyle
风格实现
- void MyStyle::polish(QPalette &palette)
- {
- palette.setBrush(QPalette::Button, Qt::red);
- }
(注意其中实现的大小写方式)。
实现数据库驱动,图像格式、文本编码和大多数其他插件类型时,一般不需要建立对象,Qt会找到他们并建立他们的对象。Style是一个特例,因为程序中科能会这样调用:
- QApplication::setStyle(QStyleFactory::create("MyStyle"));
main.c文件:
- int main(int argv, char *args[])
- {
- QApplication app(argv, args);//QT此时加载了插件
- QApplication::setStyle(QStyleFactory::create("simplestyle"));
- StyleWindow window;
- window.resize(200, 50);
- window.show();
- return app.exec();
- }
工程文件:
- TEMPLATE = lib
- CONFIG += plugin
- HEADERS = simplestyle.h \
- simplestyleplugin.h
- SOURCES = simplestyle.cpp \
- simplestyleplugin.cpp
- TARGET = simplestyleplugin
注意,插件需要设置TEMPLATE,因为我们需要的是共享库而不是执行程序。同时必须设置CONFIG。需要将此插件保存到style文件夹(应用程序所在的文件夹)。这样应用程序就能够检测得到。
底层API:没有详细研究
不管是QT本身还是QT应用程序都可以通过插件扩展。这需要应用程序检测并通过QPluginLoader进行加载。因此,插件可以提供任意功能,而不仅限于上面说的插件。
插件扩展应用包括4个步骤
1、定义插件的接口集(实际上是只有虚函数的一个类)
2、Q_DECLARE_INTERFACE宏告诉meta-object系统此接口的存在。
3、利用QPluginLoader加载插件
4、使用qobject_cast()函数测试插件实现的借口
插件编码的4个步骤
1、继承QObject定义一个插件类,并定义插件需要的接口
2、使用Q_InterFaces()宏告诉meta-object系统接口的存在
3、使用Q_EXPORT_PLUGIN2()宏输出插件
4、编译工程
例如下面例子:
接口类:
- 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 <QStringList>
- #include <QImage>
- #include <plugandpaint/interfaces.h>
- class ExtraFiltersPlugin : public QObject, public FilterInterface
- {
- Q_OBJECT
- Q_INTERFACES(FilterInterface)
- public:
- QStringList filters() const;
- QImage filterImage(const QString &filter, const QImage &image,
- QWidget *parent);
- };
定位插件
QT应用程序自动加载插件,因为插件存在标准插件的子目录中
开发过程中,插件的目录在QTDIR/plugins中(QDIR是QT安装的目录)。如果希望应用程序使用或不使用标准插件,安装会得到希望安装插件的路径,并保存路径(例如应用程序使用QSettings在启动时读取它)
应用程序可以通过QCoreApplication:addLibraryPath是插件对于应用程序可见,注意,最终的路径不能改变。
如果希望插件可被加载,一种方法是在应用程序的所在目录的子目录下保存此插件。如果想发布QT自带的任何插件,需要拷贝plugins的子目录到应用程序的根目录下。(而不是包含插件的目录)
静态插件
一般的方法是将插件做成动态库和应用程序一块发布。插件动态检测和加载。
应用程序可以静态链接。假如编译的是静态的QT库,那么静态插件就是唯一的选择了。使用静态插件可以降低错误概率。但是缺点是修改插件需要重新编译整个应用程序。
QT提供一些静态的插件:
为了静态链接插件,需要在程序中使用Q_IMPORT_PLUGIN宏,需要在编译时使用QTPLUGIN参数。例如,在main.cpp中
- #include <QApplication>
- #include <QtPlugin>
- Q_IMPORT_PLUGIN(qjpeg)
- Q_IMPORT_PLUGIN(qgif)
- Q_IMPORT_PLUGIN(qkrcodecs)
- int main(int argc, char *argv[])
- {
- QApplication app(argc, argv);
- ...
- return app.exec();
- }
工程文件中
- QTPLUGIN += qjpeg \
- qgif \
- qkrcodecs
小结:详解如何建立Qt插件学习教程的内容介绍完了,希望通过本文的学习能对你有所帮助!