QWidget应用封装为qt插件,供其他qt应用调用

news2025/1/2 21:11:58

在之前的文章中,有介绍通过QProcess的方式启动QWidget应用,然后将其窗口嵌入到其他的qt应用中,作为子窗口使用.这篇文章主要介绍qt插件的方式将QWidget应用的窗口封装为插件,然后作为其他Qt应用中的子窗口使用. 

插件优点:

与主程序为同一个进程,免去了进程间繁琐的通信方式,在不同进程间通信时,需要有一套协议来保证数据的及时性及稳定性.比较繁琐,而插件的方式,通过插件接口文件来进行通信,在接口文件中定义API,

接口文件(定义为纯虚类)(主程序通过接口文件来访问该插件,插件通过继承该接口,重写所有纯虚函数)

#pragma once

#include <QtPlugin>


QT_BEGIN_NAMESPACE
class QString;
class QWidget;
QT_END_NAMESPACE

//定义视觉检测接口
class InterfaceVisionMeasure
{
public:
    virtual ~InterfaceVisionMeasure() = default;

    /// <summary>
    /// 创建视觉窗口对象指针
    /// </summary>
    /// <param name="iLanguage">0为英文,1为中文</param>
    /// <param name="parent">父对象</param>
    /// <returns>窗口指针</returns>
    virtual void* CreatWindow(int iLanguage, QWidget* parent = nullptr) = 0;

    /// <summary>
    /// 获取对应序号轴编码器坐标
    /// </summary>
    /// <param name="GetAxisEncVal">回调对象</param>
    virtual void RegisterGetAxisEncVal(const std::function<void(int, double&)>& GetAxisEncVal) = 0;

    /// <summary>
    /// 获取对应序号轴规划位置坐标
    /// </summary>
    /// <param name="GetAxisPrfVal">回调对象</param>
    virtual void RegisterGetAxisPrfVal(const std::function<void(int, double&)>& GetAxisPrfVal) = 0;

    /// <summary>
    /// 获取内部变量的值
    /// </summary>
    /// <param name="GetVariableInVal">回调对象</param>
    virtual void RegisterGetVariableInVal(const std::function<void(int, double&)>& GetVariableInVal) = 0;

    /// <summary>
    /// 设置内部变量的值
    /// </summary>
    /// <param name="SetVariableInVal">回调对象</param>
    virtual void RegisterSetVariableInVal(const std::function<void(int, const double&)>& SetVariableInVal) = 0;

    /// <summary>
    /// 设置当前测量文件路径(测量文件)
    /// </summary>
    /// <param name="dir">测量文件路径</param>
    virtual void SetCurrentMeaureFile(const QString& dir) = 0;

    /// <summary>
    /// 开启测量
    /// </summary>
    /// <param name="indexMain">工序号</param>
    /// <param name="IndexSub">工序号中的子序号</param>
    virtual void StartMeasureProcess(int indexMain, int IndexSub) = 0;

    /// <summary>
    /// 测量结果返回到主程序
    /// </summary>
    /// <param name="MeasureResult">回调对象</param>
    virtual void RegisterMeasureResult(const std::function<void(const int&, const QStringList&, const QVector<double>&)>& MeasureResult) = 0;

    /// <summary>
    /// 创建测量文件(编辑文件)
    /// </summary>
    /// <param name="dir">创建路径</param>
    /// <returns>0为正常,非0为失败</returns>
    virtual int NewMeasureFile(const QString& dir)=0;

    /// <summary>
   /// 打开测量文件(编辑文件)
   /// </summary>
   /// <param name="dir">打开路径</param>
   /// <returns>0为正常,非0为失败</returns>
    virtual int OpenMeasureFile(const QString& dir) = 0;

    /// <summary>
    /// 另存为测量文件(编辑文件)
    /// </summary>
    /// <param name="srcDir">源文件路径</param>
    /// <param name="desDir">目标文件路径</param>
    /// <returns>0为正常,非0为失败</returns>
    virtual int SaveAsMeasureFile(const QString& srcDir, const QString& desDir) = 0;

    /// <summary>
    /// 设置当前显示页
    /// </summary>
    /// <param name="indexMain">对应工序页, -10为找中心,-11为对焦</param>
    /// <param name="indexSub">对应工序页中的第几页</param>
    /// <returns>0为成功, </returns>
    virtual int SetShowMeasurePage(int indexMain, int indexSub)=0;

    /// <summary>
    /// 获取当前测量工程工序列表(测量文件)
    /// </summary>
    /// <param name="listType">工序列表</param>
    /// <returns>0为成功</returns>
    virtual int GetCurMeasureProgram(QVector<int>& listType)=0;
};

QT_BEGIN_NAMESPACE
#define Interface_VisionMeasure_IID "Demina.Nc.VisionMeasureInterface/1.0"
Q_DECLARE_INTERFACE(InterfaceVisionMeasure, Interface_VisionMeasure_IID)
QT_END_NAMESPACE

重写接口类:   h文件

#pragma once

#include <QObject>
#include "InterfacesVisionMeasure.h"

class qcDllVisionMeasure : public QObject, public InterfaceVisionMeasure
{
    Q_OBJECT
        Q_INTERFACES(InterfaceVisionMeasure)
        Q_PLUGIN_METADATA(IID Interface_VisionMeasure_IID FILE "DllVisionMeasure.json")
public:
    qcDllVisionMeasure(QObject* parent = nullptr);
    ~qcDllVisionMeasure() override;

    /// <summary>
    /// 创建视觉窗口对象指针
    /// </summary>
    /// <param name="parent">父对象</param>
    /// <returns>窗口指针</returns>
    void* CreatWindow(int iLanguage, QWidget* parent = nullptr) override;

    /// <summary>
    /// 获取对应序号轴编码器坐标
    /// </summary>
    /// <param name="GetAxisEncVal">回调对象</param>
    void RegisterGetAxisEncVal(const std::function<void(int, double&)>& GetAxisEncVal) override;

    /// <summary>
    /// 获取对应序号轴规划位置坐标
    /// </summary>
    /// <param name="GetAxisPrfVal">回调对象</param>
    void RegisterGetAxisPrfVal(const std::function<void(int, double&)>& GetAxisPrfVal) override;

    /// <summary>
    /// 获取内部变量的值
    /// </summary>
    /// <param name="GetVariableInVal">回调对象</param>
    void RegisterGetVariableInVal(const std::function<void(int, double&)>& GetVariableInVal) override;
    //设置内部变量的值
    void RegisterSetVariableInVal(const std::function<void(int, const double&)>& SetVariableInVal) override;

    /// <summary>
    /// 设置当前测量文件路径
    /// </summary>
    /// <param name="dir">测量文件路径</param>
    void SetCurrentMeaureFile(const QString& dir) override;

    /// <summary>
    /// 开启测量
    /// </summary>
    /// <param name="indexMain">工序号</param>
    /// <param name="IndexSub">工序号中的子序号</param>
    void StartMeasureProcess(int indexMain, int IndexSub) override;

    /// <summary>
    /// 测量结果返回到主程序
    /// </summary>
    /// <param name="MeasureResult">回调对象</param>
    void RegisterMeasureResult(const std::function<void(const int&, const QStringList&, const QVector<double>&)>& MeasureResult) override;

    /// <summary>
/// 创建测量文件
/// </summary>
/// <param name="dir">创建路径</param>
/// <returns>0为正常,非0为失败</returns>
    int NewMeasureFile(const QString& dir) override;

    /// <summary>
   /// 打开测量文件
   /// </summary>
   /// <param name="dir">打开路径</param>
   /// <returns>0为正常,非0为失败</returns>
    int OpenMeasureFile(const QString& dir) override;

    /// <summary>
    /// 另存为测量文件
    /// </summary>
    /// <param name="srcDir">源文件路径</param>
    /// <param name="desDir">目标文件路径</param>
    /// <returns>0为正常,非0为失败</returns>
    int SaveAsMeasureFile(const QString& srcDir, const QString& desDir) override;

    /// <summary>
    /// 设置当前显示页
    /// </summary>
    /// <param name="indexMain">对应工序页, -10为找中心,-11为对焦</param>
    /// <param name="indexSub">对应工序页中的第几页</param>
    /// <returns>0为成功, </returns>
    int SetShowMeasurePage(int indexMain, int indexSub) override;

    /// <summary>
    /// 获取当前测量工程工序列表
    /// </summary>
    /// <param name="listType">工序列表</param>
    /// <returns>0为成功</returns>
    int GetCurMeasureProgram(QVector<int>& listType) override;
private:
    //视觉界面对象指针
    void* m_pMainWnd{};
};

在实现cpp中,封装QWidget窗口,创建其实例

#include "stdafx.h"
#include "qcDllVisionMeasure.h"
#include "qwaMeasureToolsVM.h"

qcDllVisionMeasure::qcDllVisionMeasure(QObject *parent)
:QObject(parent)
{

}

qcDllVisionMeasure::~qcDllVisionMeasure()
{

}

void* qcDllVisionMeasure::CreatWindow(int iLanguage, QWidget* parent)
{
    qwaMeasureToolsVM* widget = new qwaMeasureToolsVM(iLanguage,true,parent);
    m_pMainWnd =(void*) widget;
    return m_pMainWnd;
}

//采用回调的方式实现,插件通过回调函数来获取,设置参数
//获取对应序号轴编码器坐标
void qcDllVisionMeasure::RegisterGetAxisEncVal(const std::function<void(int, double&)>& GetAxisEncVal)
{
    if (m_pMainWnd)
    {
        ((qwaMeasureToolsVM*)m_pMainWnd)->RegisterGetAxisEncVal(GetAxisEncVal);
    }
}

//获取对应序号轴规划位置坐标
void qcDllVisionMeasure::RegisterGetAxisPrfVal(const std::function<void(int, double&)>& GetAxisPrfVal)
{

}

//获取内部变量的值
void qcDllVisionMeasure::RegisterGetVariableInVal(const std::function<void(int, double&)>& GetVariableInVal)
{
    if (m_pMainWnd)
    {
        ((qwaMeasureToolsVM*)m_pMainWnd)->RegisterGetVariableInVal(GetVariableInVal);
    }
}

//设置内部变量的值
void qcDllVisionMeasure::RegisterSetVariableInVal(const std::function<void(int, const double&)>& SetVariableInVal) 
{
    if (m_pMainWnd)
    {
        ((qwaMeasureToolsVM*)m_pMainWnd)->RegisterSetVariableInVal(SetVariableInVal);
    }
}

/// <summary>
   /// 设置当前测量文件路径
   /// </summary>
   /// <param name="dir">测量文件路径</param>
void qcDllVisionMeasure::SetCurrentMeaureFile(const QString& dir)
{
    if (m_pMainWnd)
    {
        ((qwaMeasureToolsVM*)m_pMainWnd)->SetCurrentMeaureFileByMainApp(dir);
    }
}

/// <summary>
/// 开启测量
/// </summary>
/// <param name="indexMain">工序号</param>
/// <param name="IndexSub">工序号中的子序号</param>
void qcDllVisionMeasure::StartMeasureProcess(int indexMain, int IndexSub)
{
    if (m_pMainWnd)
    {
        ((qwaMeasureToolsVM*)m_pMainWnd)->StartMeasureProcessByMainApp(indexMain, IndexSub);
    }
}

/// <summary>
/// 测量结果返回到主程序
/// </summary>
/// <param name="MeasureResult">回调对象</param>
void qcDllVisionMeasure::RegisterMeasureResult(const std::function<void(const int&, const QStringList&, const QVector<double>&)>& MeasureResult)
{
    if (m_pMainWnd)
    {
        ((qwaMeasureToolsVM*)m_pMainWnd)->RegisterMeasureResult(MeasureResult);
    }
}

/// <summary>
/// 创建测量文件
/// </summary>
/// <param name="dir">创建路径</param>
/// <returns>0为正常,非0为失败</returns>
int qcDllVisionMeasure::NewMeasureFile(const QString& dir)
{
    if (m_pMainWnd)
    {
       return ((qwaMeasureToolsVM*)m_pMainWnd)->NewMeasureFile(dir);
    }

    return -1;
}

/// <summary>
/// 打开测量文件
/// </summary>
/// <param name="dir">打开路径</param>
/// <returns>0为正常,非0为失败</returns>
int qcDllVisionMeasure::OpenMeasureFile(const QString& dir) 
{
    if (m_pMainWnd)
    {
        return ((qwaMeasureToolsVM*)m_pMainWnd)->OpenMeasureFile(dir);
    }
    return -1;
}

/// <summary>
/// 另存为测量文件
/// </summary>
/// <param name="srcDir">源文件路径</param>
/// <param name="desDir">目标文件路径</param>
/// <returns>0为正常,非0为失败</returns>
int qcDllVisionMeasure::SaveAsMeasureFile(const QString& srcDir, const QString& desDir) 
{ 
    if (m_pMainWnd)
    {
        return ((qwaMeasureToolsVM*)m_pMainWnd)->SaveAsMeasureFile(srcDir, desDir);
    }
    return -1;
}

/// <summary>
/// 设置当前显示页
/// </summary>
/// <param name="indexMain">对应工序页, -10为找中心,-11为对焦</param>
/// <param name="indexSub">对应工序页中的第几页</param>
/// <returns>0为成功, </returns>
int qcDllVisionMeasure::SetShowMeasurePage(int indexMain, int indexSub) 
{ 
    if (m_pMainWnd)
    {
        return ((qwaMeasureToolsVM*)m_pMainWnd)->SetShowMeasurePage(indexMain, indexSub);
    }
    return -1;
}

/// <summary>
/// 获取当前测量工程工序列表
/// </summary>
/// <param name="listType">工序列表</param>
/// <returns>0为成功</returns>
int qcDllVisionMeasure::GetCurMeasureProgram(QVector<int>& listType) 
{ 
    if (m_pMainWnd)
    {
        return ((qwaMeasureToolsVM*)m_pMainWnd)->GetCurMeasureProgram(listType);
    }
    return -1;
}

 json接口描述json文件,放在头文件同目录

{
  "Type": ["BT150D"],
  "Name": "VisionMeasure",
  "Description": "this is vision measure tools.",
  "Version": "1.0.0",
  "Vendor": "demina"
}

设置工程生成为从exe改为dll

将qt插件功能启动

至此重新封装QWdiget结束, 等待生成的dll,将其复制到主程序的exe文件路径下即可.

在主程序中要做的工作,即通过接口文件 声明一个接口实例指针.

bool NcCoreQt::InitPluginVisionMeasure()
{
   
    QString dir = qApp->applicationDirPath();
 
    dir += "/VisionMeasure.dll";//视觉插件的dll

    m_pPluginLoaderVM = new QPluginLoader(dir, this);
    QObject* plugin = m_pPluginLoaderVM->instance();
    //qDebug() << pluginLoader.metaData();
    if (plugin) {
        m_pInterfaceVM = qobject_cast<InterfaceVisionMeasure*>(plugin);
        if (m_pInterfaceVM)
        { 
            qInfo() << tr("Load vision measure interface successful");
            return true;
        }
    }
    else
    {
        qDebug() << m_pPluginLoaderVM->errorString();
    }

    return false;
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

关于 覆铜与导线之间间距较小需要增加间距 的解决方法

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/144776995 长沙红胖子Qt&#xff08;长沙创微智科&#xff09;博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV…

ArcGIS教程(009):ArcGIS制作校园3D展示图

文章目录 数据下载校园3D展示图制作创建要素类矢量化【楼】要素矢量化【绿地】矢量化【范围】矢量化处理打开ArcScene添加动画数据下载 https://download.csdn.net/download/WwLK123/90189025校园3D展示图制作 创建要素类 添加底图: 新建【文件地理数据库】,并修改名称为【…

权限注解+AOP切面+额外工具(UUID生成id,JWT,Servlet客户端,字符串String工具类,Redis序列化,ip工具类)

权限功能和注解的关系 ①、定义三个注解 //角色认证&#xff0c;必须具有指定角色标识才能进入该方法 Retention(RetentionPolicy.RUNTIME) Target({ElementType.METHOD,ElementType.TYPE}) public interface RequiresRoles{//需要校验的角色标识String[] value() default {}…

RGB、HSV颜色模型及MATLAB互换应用实例

一、前言 RGB和HSV模型是数字图像处理中颜色空间中的两种重要表示方式&#xff0c;RGB和HSV都是描述颜色的数学模型&#xff0c;可以用于表示和处理图像中的颜色信息。 RGB模型是一种基于光的颜色模型&#xff0c;由红&#xff08;Red&#xff09;、绿&#xff08;Green&#x…

MySQL基础-常见的增删改查操作语句总结

1.数据库操作 查看所有数据库 show databases;创建数据库 create database db_stu; --如果数据库已经存在就不创建 create database if not exists db_stu; --添加默认字符集 create database db_stu default charset utf8mb4;删除数据库 drop database db_stu; --如果存在…

【运维】部署MKDocs

部署MKDocs obsidian 记录笔记&#xff0c;通过 mkdocs 私有化部署。 1 使用MKDocs创建笔记 创建仓库&#xff0c;安装 Material for MkDocs 和 mkdocs-minify-plugin mkdir tmp cd tmp git initpip install mkdocs-material pip install mkdocs-minify-pluginmkdocs new .2 …

黑马Java面试教程_P2_MySQL

系列博客目录 文章目录 系列博客目录前言1. 优化1.1 MySQL中&#xff0c;如何定位慢查询&#xff1f;面试文稿 1.2 面试官接着问&#xff1a;那这个SQL语句执行很慢,如何分析 ( 如何优化&#xff09;呢?面试文稿 1.3 了解过索引吗?(什么是索引)1.4 继续问 索引的底层数据结构…

【优选算法】盛最多水的容器(双指针算法)

11. 盛最多水的容器 - 力扣&#xff08;LeetCode&#xff09; 【1.题目】 【2.算法原理】 【3.代码编写】 优化之后就遍历了一遍数组&#xff0c;时间复杂度变为O(N)&#xff0c;就使用了几个变量&#xff0c;空间复杂度为O(1)。 class Solution { public:int maxArea(vecto…

安装torch-geometric库

目录 1.查看 torch 和 CUDA 版本 2.依次下载和 torch 和 CUDA 对应版本的四个依赖库pyg-lib、torch-scatter、torch-sparse、torch-cluster以及torch-spline-conv 3.下载并安装torch-geometric库 1.查看 torch 和 CUDA 版本 查看CUDA版本 nvcc -V 查看pytorch版本 pip s…

王佩丰24节Excel学习笔记——第十八讲:Lookup和数组

【以 Excel2010 系列学习&#xff0c;用 Office LTSC 专业增强版 2021 实践】 【本章技巧】 地址栏公式可以使用 F9 查看&#xff0c;取消请按Esc键&#xff0c;或者公式前的红色叉&#xff1b;使用数组时一定要注意使用绝对引用&#xff0c;方便下拉&#xff1b;使用数组时一…

【hackmyvm】hacked靶机wp

tags: HMVrootkitDiamorphine Type: wp 1. 基本信息^toc 文章目录 1. 基本信息^toc2. 信息收集2.1. 端口扫描2.2. 目录扫描2.3. 获取参数 3. 提权 靶机链接 https://hackmyvm.eu/machines/machine.php?vmHacked 作者 sml 难度 ⭐️⭐️⭐️⭐️️ 2. 信息收集 2.1. 端口扫描…

【超级详细】七牛云配置阿里云域名详细过程记录

0. 准备一个阿里云域名&#xff0c;记得要备案&#xff01;&#xff01;&#xff01;&#xff01; 1. 创建七牛云存储空间 首先&#xff0c;登录七牛云控制台&#xff0c;创建一个新的存储空间&#xff08;Bucket&#xff09;。这个存储空间将用于存放你的文件&#xff0c;并…

【JDBC】转账案例

回顾 使用工具类查询表 需求&#xff1a; 查询student表的所有数据&#xff0c;把数据封装到一个集合中 数据准备 #创建表 CREATE TABLE student( sid INT, name VARCHAR(100), age INT, sex VARCHAR(100) ) #插入数据 INSERT INTO student VALUES(1,张三,18,女),(2…

HTML——14. 超链接四种状态

<!DOCTYPE html> <html><head><meta charset"UTF-8"><title>超链接</title></head><body><a href"https://ai.m.taobao.com" target"_blank">淘宝</a><br /><a href"…

微信V3支付报错 平台证书及平台证书序列号

1.平台证书及平台证书序列号设置错误报错&#xff1a; 错误1&#xff1a; Verify the response’s data with: timestamp1735184656, noncea5806b8cabc923299f8db1a174f3a4d0, signatureFZ5FgD/jtt4J99GKssKWKA/0buBSOAbWcu6H52l2UqqaJKvrsNxvodB569ZFz5G3fbassOQcSh5BFq6hvE…

MusicFree - 免费播放全网歌曲!无广告开源网络音乐聚合播放器 (安卓电脑版)

大家平常听歌可能都会在 QQ 音乐、网易云音乐、酷狗、喜马拉雅等不同平台来回切换&#xff0c;体验其实很烦。曾经推荐过不少“聚合”音乐应用&#xff0c;比如 洛雪音乐助手、Listen1 等等。 最近又有一个新选择了&#xff01;MusicFree 是一款免费开源清爽无广告的音乐播放器…

C++的第一个程序

前言 在学习c之前&#xff0c;你一定还记得c语言的第一个程序 当时刚刚开始进行语言学习 因此告诉到&#xff0c;仅仅需要记住就可以 #include <stdio.h>int main(){printf("Hello World");return 0; }而对于c中的第一个程序&#xff0c;似乎有所变化 C的…

代码随想录算法【Day1】

Day1 1.掌握二分法边界值判断&#xff0c;是根据写法来的; 2.删除数组元素的双指针和暴力解法; 3.灵活使用双指针方法 704 二分法 以前对于边界的问题非常纠结&#xff0c;到底是<还是<&#xff0c;以及是mid还是mid-1。 通过视频讲解&#xff0c;得知二分法的两种…

探索CSDN博客数据:使用Python爬虫技术

探索CSDN博客数据&#xff1a;使用Python爬虫技术 在数字化的浪潮中&#xff0c;数据的获取与分析变得日益关键。CSDN作为中国领先的IT社区和服务平台&#xff0c;汇聚了海量的技术博客与文章&#xff0c;成为一座蕴藏丰富的数据宝库。本文将引领您穿梭于Python的requests和py…

实战案例——ZooKeeper集群部署(新手教程超详细)

案例目标 了解ZooKeeper分布式应用程序协调服务使用3台机器搭建ZooKeeper集群使用ZooKeeper集群 案例分析 规划节点 ZooKeeper集群节点规划 Ip 主机名 节点 192.168.110.10 zookeeper1 集群节点 192.168.110.20 zookeeper2 集群节点 192.168.110.30 zookeeper3 …