文章目录
- 前言
- 插件的好处
- 具体流程
- 1. 第一,我们先创建一个主框架应用(**第一个工程**)
- 2. GUI 设计 ![在这里插入图片描述](https://img-blog.csdnimg.cn/f215270ccfac4e038e7261c4b4891ec1.png)
- 3. 创建动态库项目(**第2个工程**)
- 4. 给插件项目添加qt界面类
- 5.在插件工程添加一个头文件
- 6. 编辑上面新建的头文件
- 7.编辑插件工程的头文件和cpp文件
- 8.去掉插件工程的影子编译
- 9.找到插件的文件路径
- 10.将PluginInterface.h添加到主框架中
- 11.把插件工程的dll文件也拷贝到主框架工程中![在这里插入图片描述](https://img-blog.csdnimg.cn/61bea6b54d2848a3a40a08887d3c8b6c.png)
- 12. 打开主框架界面头文件
- 13.mainwindow.cpp
- 补充:这个博主我真的栓q,很多细节没有讲
- 1. error: Undefined interface=>这个非常重要,在沟通插件工程与主框架工程的这个头文件中,必须加上这个!!!
- 2. error: C2039: "qt_metacall"
- 3.error: C2039: "staticMetaObject": 不是 "PluginInterface" 的成员
- 4.error: C2338: qobject_cast requires the type to have a Q_OBJECT macro
- 5.error: C2440: “static_cast”: 无法从“QObject *”转换为“T”
- 效果
- 运行
- 点击
- 代码结构
- 代码地址
- 教程
前言
qt插件我虽然没用过,但是最近看了很多有关三维软件的开发,都是用qt做的,其中就用到了qt插件开发,今天来圆一下梦 : 终于有时间来填一下这方面知识的坑了!
插件的好处
-
- 减少主程序体积和占用内存大小
-
- 按模块升级不会影响到其他
-
- 效率高和维护成本低
具体流程
我们需要创建两个工程
1. 第一,我们先创建一个主框架应用(第一个工程)
2. GUI 设计
3. 创建动态库项目(第2个工程)
文件->New Project->
4. 给插件项目添加qt界面类
加一个label:
5.在插件工程添加一个头文件
6. 编辑上面新建的头文件
#ifndef PLUGININTERFACE_H
#define PLUGININTERFACE_H
#include <QWidget>
#define PluginInterfaceIID "com.szweebon.PluginInterface/1.0.0"
class PluginInterface{
public:
virtual ~PluginInterface() = default;
virtual QWidget *getWidget() = 0;
};
#endif // PLUGININTERFACE_H
7.编辑插件工程的头文件和cpp文件
#ifndef PLUGININTERFACE_H
#define PLUGININTERFACE_H
#include <QWidget>
#define PluginInterfaceIID "com.szweebon.PluginInterface/1.0.0"
class PluginInterface{
public:
virtual ~PluginInterface() = default;
virtual QWidget *getWidget() = 0;
};
Q_DECLARE_INTERFACE(PluginInterface,PluginInterfaceIID)//此宏必须定义,否则外部程序会报错。
#endif // PLUGININTERFACE_H
#include "plugindemo.h"
#include "form.h"
PluginDemo::PluginDemo()
{
mGenWidget = Q_NULLPTR;
}
PluginDemo::~PluginDemo()
{
if(mGenWidget){
mGenWidget->deleteLater();
}
}
QWidget *PluginDemo::getWidget()
{
if(!mGenWidget){
mGenWidget = new Form;
}
return mGenWidget;
}
8.去掉插件工程的影子编译
9.找到插件的文件路径
10.将PluginInterface.h添加到主框架中
11.把插件工程的dll文件也拷贝到主框架工程中
我发现主框架目录有两个位置都有可执行目录,
我直接两个全放了,如下:
12. 打开主框架界面头文件
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QPluginLoader>//插件加载类
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_pushButton_clicked();
private:
Ui::MainWindow *ui;
QPluginLoader loader;
};
#endif // MAINWINDOW_H
13.mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "PluginInterface.h"
#include <QDir>
#include <QMessageBox>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
if(loader.isLoaded())
{
loader.unload();
}
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
QDir dir("F:/QT_code/1study/tetsPlugIn/Debug/debug");
//QDir dir(qApp->applicationDirPath());//加载当前运行目录
qDebug("目录1:%s",dir.path().toUtf8().constData());
loader.setFileName(dir.filePath("PluginDemo.dll"));//将加载器的目录加载进来
qDebug("目录2:%s",dir.filePath("PluginDemo.dll").toUtf8().constData());
if(!loader.load())
{
qDebug("Failed to load loader");
QMessageBox::critical(this,"Tips",loader.errorString());
return ;
}
//实例化
QObject *plugin = loader.instance();
qDebug() << __FUNCTION__ << loader.errorString();
if(plugin==NULL)
{
qDebug("loader.instance() is null");
return;
}
qDebug("Success1");
PluginInterface *pi = qobject_cast<PluginInterface *>(plugin);
if(pi)
{
QWidget * w = pi->getWidget();
qDebug("Success2");
if(w)
{
ui->tabWidget->addTab(w,"hello plugin");
qDebug("Success3");
}
qDebug("Success4");
}else{
qDebug("pi is NULL");
}
}
补充:这个博主我真的栓q,很多细节没有讲
1. error: Undefined interface=>这个非常重要,在沟通插件工程与主框架工程的这个头文件中,必须加上这个!!!
Q_DECLARE_INTERFACE(PluginInterface,PluginInterfaceIID)//此宏必须定义,否则外部程序会报错。
2. error: C2039: “qt_metacall”
3.error: C2039: “staticMetaObject”: 不是 “PluginInterface” 的成员
4.error: C2338: qobject_cast requires the type to have a Q_OBJECT macro
由于在使用qobject_cast时,类型没有使用Q_OBJECT宏定义导致的
5.error: C2440: “static_cast”: 无法从“QObject *”转换为“T”
还是PluginInterface *pi = qobject_cast<PluginInterface *>(loader.instance());
报错
解决:PluginInterface 要继承QObject
效果
运行
点击
代码结构
代码地址
代码地址
教程
教程