Qt插件开发_入门教程

文章目录

  • 前言
  • 插件的好处
  • 具体流程
    • 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. 减少主程序体积和占用内存大小
    1. 按模块升级不会影响到其他
    1. 效率高和维护成本低

具体流程

我们需要创建两个工程

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_NAMESPACEclass MainWindow : public QMainWindow
{Q_OBJECTpublic: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
在这里插入图片描述

效果

运行

在这里插入图片描述

点击

在这里插入图片描述
在这里插入图片描述

代码结构

在这里插入图片描述

代码地址

代码地址

教程

教程

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/164421.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于YOLOv8与DeepSORT实现多目标跟踪——算法与源码解析

一、概述 "目标跟踪 (Object Tracking)"是机器视觉领域中的一个重要研究领域。根据跟踪的目标数量&#xff0c;可以将其分为两大类&#xff1a;单目标跟踪 (Single Object Tracking&#xff0c;简称 SOT) 和多目标跟踪 (Multi Object Tracking&#xff0c;简称 MOT)…

20道高频CSS面试题快问快答

面试中的快问快答 快问快答的情景在面试中非常常见。 在面试过程中&#xff0c;面试官通常会使用快问快答的方式来快速评估面试者的基础知识、思维能力和反应速度。 这种情景下&#xff0c;面试官会提出一系列简短的问题&#xff0c;并期望面试者能够迅速做出回答或提供简洁明…

使用request库的get方法发起GET请求

// 导入所需的库 const request require(request); const cheerio require(cheerio);// 设置代理信息&#xff0c;proxy_host: www.duoip.cn, proxy_port: 8000 const proxy {host: jshk.com.cn,port: 1234 };// 定义要爬取的URL const url http://localhost:9200/_cat/ind…

蓝桥杯:分数

题目 思路 等比数列求和&#xff0c;手算然后输出 代码&#xff08;已过&#xff09; #include <iostream> using namespace std; int main() {// 请在此输入您的代码int a1024*1024-1;int b1024*512;cout<<a<<"/"<<b;return 0; }

Pytest系列(16)- 分布式测试插件之pytest-xdist的详细使用

前言 平常我们功能测试用例非常多时&#xff0c;比如有1千条用例&#xff0c;假设每个用例执行需要1分钟&#xff0c;如果单个测试人员执行需要1000分钟才能跑完当项目非常紧急时&#xff0c;会需要协调多个测试资源来把任务分成两部分&#xff0c;于是执行时间缩短一半&#…

Leetcode—2586.统计范围内的元音字符串数【简单】

2023每日刷题&#xff08;二十二&#xff09; Leetcode—2586.统计范围内的元音字符串数 实现代码 class Solution { public:int vowelStrings(vector<string>& words, int left, int right) {int ans 0;for(int i left; i < right; i) {string s words[i];i…

抽象工厂模式 rust和java的实现

文章目录 抽象工厂模式介绍抽象工厂模式包含以下几个核心角色&#xff1a;实现架构图java实现rust实现rust代码仓库 抽象工厂模式 抽象工厂模式&#xff08;Abstract Factory Pattern&#xff09;是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。 在抽象工…

DDD技术方案落地实践 | 京东云技术团队

1. 引言 从接触领域驱动设计的初学阶段&#xff0c;到实现一个旧系统改造到DDD模型&#xff0c;再到按DDD规范落地的3个的项目。对于领域驱动模型设计研发&#xff0c;从开始的各种疑惑到吸收各种先进的理念&#xff0c;目前在技术实施这一块已经基本比较成熟。在既往经验中总…

【机器学习】六、概率图模型

今天我们对概率图模型&#xff08;Probabilistic Graphical Model&#xff0c;PGM&#xff09;做一个总结。 模型表示 概率图模型&#xff0c;是指一种用图结构来描述多元随机变量之间条件独立关系的概率模型。 它提出的背景是为了更好研究复杂联合概率分布的数据特征&#x…

【Git】Git 学习笔记_操作本地仓库

1. 安装与初始化配置 1.1 安装 下载地址 在文件夹里右键点击 git bash here 即可打开命令行面板。 git -v // 查看版本1.2 配置 git config --global user.name "heo" git config --global user.email xxxgmail.com git config --global credential.helper stor…

总决赛再获佳绩!开源网安斩获CCIA2023年网络安全优秀创新成果大赛总决赛大奖

​近日&#xff0c;由中央网信办网络安全协调局指导&#xff0c;中国网络安全产业联盟&#xff08;CCIA&#xff09;主办的“2023年网络安全优秀创新成果大赛”总决赛及颁奖典礼在武汉成功举办。开源网安创新产品“实时应用自我防护平台&#xff08;RASP&#xff09;”从200余家…

PyCharm 无法登陆 Codeium 的解决方法

PyCharm 登陆 Codeium PyCharm 无法登陆 Codeium 的问题描述PyCharm 使用 token 登陆 Codeium PyCharm 无法登陆 Codeium 的问题描述 使用 PyCharm 登录 Codeium 时&#xff0c;单击 Login 无反应&#xff0c;单击侧边栏的 Codeium 图标也一直显示连接失败。 PyCharm 使用 to…