版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq78442761/article/details/86736245
目录
官方解析
Qt应用程序可以对插件进行扩展,要使用QPluginLoader这个类进行加载。插件可以提供任意的功能,而且不限制数据库驱动,图像格式,以及其他的Qt功能插件。
当调用插件时要有如下的过程:
1. 定义一个抽象类作为接口,用于调用插件;
2. 使用Q_DECLARE_INTERFACE()宏告诉Qt元对象系统,这是一个接口类;
3. 使用QPluginLoader加载插件;
4. 使用qobject_cast去尝试把插件实例转换为 接口。
写插件包含的过程:
1. 写一个插件类,这个类继承了QObject和调用插件时写的那个接口类;
2. 使用Q_INTERFACES()宏告诉元对象,这个哪个类是接口;
3. 使用Q_EXPORT_PLUGIN2()宏用于导出插件;
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 <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);
};
博主栗子
下面举一个插件生成和调用的例子,程序运行截图如下:
调用插件端:
当点击Test后,调用插件界面:
插件端源码如下:
AppInterface.h
#ifndef APPINTERFACE_H
#define APPINTERFACE_H
#include <QtPlugin>
class AppInterface{
public:
virtual ~AppInterface(){}
virtual QString pluginName() const = 0;
virtual QWidget *createWidget() = 0;
};
Q_DECLARE_INTERFACE(AppInterface, "com.AppInterface");
#endif //APPINTERFACE_H
HelloWidget.h
#ifndef HELLOWIDGET_H
#define HELLOWIDGET_H
#include <QObject>
#include "AppInterface.h"
class HelloWidget: public QObject, public AppInterface{
Q_OBJECT
Q_INTERFACES(AppInterface)
public:
HelloWidget();
~HelloWidget();
QString pluginName() const;
QWidget *createWidget();
};
#endif
HelloWidget.cpp
#include "HelloWidget.h"
#include "MyWidget.h"
HelloWidget::HelloWidget(){
}
HelloWidget::~HelloWidget(){
}
QString HelloWidget::pluginName() const{
return "Plugin";
}
QWidget *HelloWidget::createWidget(){
return new MyWidget;
}
Q_EXPORT_PLUGIN2("helloWidget", HelloWidget);
MyWidget.h
#ifndef MYWIDGET_H
#define MYWIDGET_H
#include <QWidget>
class MyWidget : public QWidget{
Q_OBJECT
public:
MyWidget(QWidget *parent = 0);
~MyWidget();
};
#endif
MyWidget.cpp
#include "MyWidget.h"
#include <QPushButton>
#include <QVBoxLayout>
MyWidget::MyWidget(QWidget *parent): QWidget(parent){
QPushButton *button = new QPushButton("Test Button");
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(button);
setLayout(layout);
}
MyWidget::~MyWidget(){
}
MyWidget.pro
TARGET = HelloWidget
TEMPLATE = lib
CONFIG += plugin
SOURCES += \
MyWidget.cpp\
HelloWidget.cpp
HEADERS += \
AppInterface.h\
HelloWidget.h\
MyWidget.h
插件调用端:
AppInterface.h
#ifndef APPINTERFACE_H
#define APPINTERFACE_H
#include <QtPlugin>
class AppInterface{
public:
virtual ~AppInterface(){}
virtual QString pluginName() const = 0;
virtual QWidget *createWidget() = 0;
};
Q_DECLARE_INTERFACE(AppInterface, "com.AppInterface");
#endif //APPINTERFACE_H
Widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
class Widget : public QWidget{
Q_OBJECT
public:
Widget(QWidget *parent = 0);
~Widget();
protected slots:
void btnClicked();
};
#endif //WIDGET_H
Widget.cpp
#include <QDir>
#include <QApplication>
#include <QPluginLoader>
#include <QDebug>
Widget::Widget(QWidget *parent) : QWidget(parent){
QPushButton *button = new QPushButton("Test");
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(button);
setLayout(layout);
connect(button, SIGNAL(clicked()), this, SLOT(btnClicked()));
}
Widget::~Widget(){
}
void Widget::btnClicked(){
//QMessageBox::information(this, "tip", "HelloWidget");
QDir pluginsDir(qApp->applicationDirPath() + "/Plugin");
foreach(QString fileName, pluginsDir.entryList(QDir::Files)){
QPluginLoader pluginLoader(pluginsDir.absoluteFilePath(fileName));
QObject *plugin = pluginLoader.instance();
if(plugin){
qDebug() << plugin;
AppInterface *app = qobject_cast<AppInterface*>(plugin);
if(app){
QWidget *widget = qobject_cast<QWidget*>(app->createWidget());
widget->show();
}
}
else{
QMessageBox::information(this, "tip", "load plugin error");
}
}
}
main.cpp
#include "Widget.h"
#include <QApplication>
int main(int argc, char *argv[]){
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
CallPlugin.pro
QT += core gui
TARGET = CallPlugin
TEMPLATE = app
SOURCES += Widget.cpp\
main.cpp
HEADERS += Widget.h\
AppInterface.h