Qt5学习笔记之子程序与插件
好的经验要乐于分享
前言
本次想要分享的是在QT5环境下,如何做一个子项目模式的,插件调用的操作内容。这部分是一部分参考别人的方法,一部分自行摸索的结果。
分享如下
一、创建一个子项目
先正常创建一个含有子项目的工程-创建一个主子工程
1.新建其他项目-子目录项目-Choose
2.我这里起名叫TestProject
3.选一个好用版本
4.生成项目
5.这里会自动弹出一个窗口,让你新建一个子项目,这里我新建一个标准的MainWindow,直接跳到最后
二、配置插件头文件
以下介绍了如果要在主子程序配置相关插件的首要配置工作:
1.在主子程序中新建一个头文件
2.命名为MainGetPlugin.h
3.内容为
#ifndef MAINGETPLUGIN_H
#define MAINGETPLUGIN_H
#include<QObject>
class MainGetPlugin
{
public:
virtual ~MainGetPlugin(){}
//声明纯虚函数的一般形式是 virtual 函数类型 函数名 (参数表列) = 0;
virtual QString name() const = 0;
};
//这些名字什么的都随便起,前后用的一样就行,这个就不多说了
#define MAINGETPLUGININTERFACE_IID "com.MainGetPlugin.mainGetInterface/1.0"
Q_DECLARE_INTERFACE(MainGetPlugin, MAINGETPLUGININTERFACE_IID)
#endif // MAINGETPLUGIN_H
三、新建插件Library工程
1.基于TestProject项目新建PluginTest的library工程
2.基于TestProject项目新建PluginTest的library工程
3.PluginTest.pro补充以下内容
# 告诉大家我是接口
CONFIG += c++11 plugin
# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
# 添加接口文件路径
INCLUDEPATH += ../MainWindow
CONFIG(debug, debug|release) {
DESTDIR = $$PWD/../bin/debug/plugins
}else{
DESTDIR = $$PWD/../bin/release/plugins
}
4.MainWindow.pro补充以下内容
CONFIG(debug, debug|release) {
DESTDIR = $$PWD/../bin/debug
}else{
DESTDIR = $$PWD/../bin/release
}
win32:CONFIG(release, debug|release) {
INCLUDEPATH += $$PWD/../bin/release/plugins
DEPENDPATH += $$PWD/../bin/release/plugins
}
else:win32:CONFIG(debug, debug|release) {
INCLUDEPATH += $$PWD/../bin/debug/plugins
DEPENDPATH += $$PWD/../bin/debug/plugins
}
5.PluginTest中新增文件plugintest.json,内容为
{"keys":["plugintest"]}
6.修改plugintest.h中内容为
#ifndef PLUGINTEST_H
#define PLUGINTEST_H
#include "PluginTest_global.h"
#include "MainGetPlugin.h"
class PLUGINTEST_EXPORT PluginTest :public QObject,MainGetPlugin
{
//添加内容
Q_OBJECT
Q_PLUGIN_METADATA(IID"com.MainGetPlugin.mainGetInterface/1.0" FILE "plugintest.json")
Q_INTERFACES(MainGetPlugin)
public:
PluginTest();
QString name() const{
return "this is plugintest";
}
};
#endif // PLUGINTEST_H
四、从主工程中引入插件
代码如下(示例):
1.修改mainwindow.h内容为
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "MainGetPlugin.h"
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
int loadPlugins();//接入插件
};
#endif // MAINWINDOW_H
2.修改mainwindow.cpp内容为
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDir>
#include <QPluginLoader>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
loadPlugins();
}
MainWindow::~MainWindow()
{
delete ui;
}
//接入插件
int MainWindow::loadPlugins()
{
int count = 0;
QDir pluginsDir = QDir(qApp->applicationDirPath());
qDebug() << "start getting plugin";
if(!pluginsDir.cd("plugins"))
{
qDebug() << "no plugins Dir";
return -1;
}
qDebug() << "start searching plugin";
foreach (QString fileName, pluginsDir.entryList(QDir::Files))
{
QFileInfo pluginFileInfo(fileName);
if (pluginFileInfo.completeSuffix() == "dll" ||
pluginFileInfo.completeSuffix() == "so")
{
qDebug() << "Search Dir " << fileName;
QPluginLoader pluginLoader(pluginsDir.absoluteFilePath(fileName));
QObject *plugin = pluginLoader.instance();
if(plugin)
{
MainGetPlugin *pluginGet = qobject_cast<MainGetPlugin *>(plugin);
++count;
qDebug() << "load plugin successed:" << pluginGet->name();
}
else
{
qDebug() << "load plugin failed";
}
}
}
return count;
}
五、效果展示
1.运行效果
可以看到在指定目录下生成了对应的dll,我理解后续此工程内的类就可以被主子程序引用了。当然,本文所说到得“主子程序”只是为了区分插件程序,并不存在什么真正的主子程序的说法。
总结
以上为本次总结内容,希望对大家有所帮助,也为自己未来回顾起到一定帮助作用。
参考链接:
QT之插件Plugin生成与使用