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

在之前的文章中,有介绍通过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;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

人工智能与云计算的结合:如何释放数据的无限潜力?

引言&#xff1a;数据时代的契机 在当今数字化社会&#xff0c;数据已成为推动经济与技术发展的核心资源&#xff0c;被誉为“21世纪的石油”。从个人消费行为到企业运营决策&#xff0c;再到城市管理与国家治理&#xff0c;每个环节都在生成和积累海量数据。然而&#xff0c;数…

使用seata实现分布式事务管理

配置 版本说明&#xff1a;springCloud Alibaba组件版本关系 我用的是spring cloud Alibaba 2.2.1.RELEASE 、springboot 2.2.1.RELEASE、nacos 2.0.1、seata1.2.0,jdk1.8 seata 主要用于在分布式系统中对数据库进行事务回滚&#xff0c;保证全局事务的一致性。 seata的使用…

前端node.js

一.什么是node.js 官网解释:Node.js 是一个开源的、跨平台的 JavaScript 运行时环境。 二.初步使用node.js 需要区分开的是node.js和javascript互通的只有console和定时器两个API. 三.Buffer Buffer 是一个类似于数组的对象&#xff0c;用于表示固定长度的字节序列。 Buffer…

LoRA微调系列笔记

系列文章目录 第一章&#xff1a;LoRA微调系列笔记 第二章&#xff1a;Llama系列关键知识总结 第三章&#xff1a;LLaVA模型讲解与总结 文章目录 系列文章目录LoRA&#xff1a;Low-Rank Adaptation of Large Language Models目的&#xff1a;依据&#xff1a;优势&#xff1a;…

khadas edge2安装ubuntu22.04与ubuntu20.04 docker镜像

khadas edge2安装ubuntu22.04与ubuntu20.04 docker镜像 一、资源准备1.1 镜像文件1.2 刷机工具1.3 ubuntu20.04 docker镜像&#xff08;具备demon无人机所需各种驱动&#xff09; 二、开始刷机&#xff08;安装ubuntu22.04系统&#xff09;2.1 进入刷机状态2.2 刷机 三、docker…

PhPMyadmin-cms漏洞复现

一.通过日志文件拿Shell 打开靶场连接数据库 来到sql中输入 show global variables like %general%; set global general_logon; //⽇志保存状态开启&#xff1b; set global general_log_file D:/phpstudy/phpstudy_pro/WWW/123.php //修改日志保存位置 show global varia…

FPGA流水线考虑因素

流水线考虑因素 另一种提升性能的方法是对拥有多个逻辑级数的长数据路径进行重新组织&#xff0c;并将其分配在多个时钟周期上。这种方法 以时延和流水线开销逻辑管理为代价&#xff0c;来达到加快时钟周期和提高数据吞吐量的目的。 由于 FPGA 器件带有大量的寄存器&#x…

语言模型的革命:大型概念模型(LCM)的崛起

在人工智能领域&#xff0c;Meta最近推出的一项重大突破正在引起研究人员和开发者的广泛关注&#xff1a;大型概念模型&#xff08;Large Concept Models&#xff0c;简称LCM&#xff09;。这一创新彻底改变了我们对语言模型的理解&#xff0c;并为未来AI技术的进展指明了新的方…

郴州年夜饭大数据分析:Python爬虫的美味之旅

在春节这个阖家团圆的日子里&#xff0c;年夜饭无疑是最具仪式感的一餐。郴州&#xff0c;这座美食之城&#xff0c;其年夜饭的餐桌上自然少不了那些让人垂涎三尺的地道美食。作为一名热爱美食的程序员&#xff0c;我决定用Python爬虫技术&#xff0c;为大家揭秘郴州年夜饭的必…

STM32-笔记17-PWM波型

一、介绍 PWM波形&#xff08;Pulse Width Modulation&#xff0c;脉冲宽度调制波形&#xff09;是一种占空比可变的脉冲波形。这种调制方式通过改变脉冲的宽度来控制电路中的信号强度和频率。具体来说&#xff0c;PWM波形中的高电平持续时间和低电平持续时间可以根据需要进行调…

HTML——16.相对路径

<!DOCTYPE html> <html><head><meta charset"UTF-8"><title></title></head><body><a href"../../fj1/fj2/c.html" target"_blank">链接到c</a><!--相对路径&#xff1a;-->…

【学生管理系统】整合JWT(完)

目录 5. 整合JWT 5.1 生成Token 5.2 携带Token 5.2.1 保存token 5.2.2 携带token 5.3 校验Token 5.4 获得Token 5. 整合JWT 5.1 生成Token 用户登录成功后&#xff0c;通过工具类&#xff0c;将用户信息转换成token 步骤&#xff1a; 拷贝工具类&#xff0c;及其Prop…

java计算机毕设课设—商品供应管理系统(附源码、文章、相关截图、部署视频)

这是什么系统&#xff1f; 资源获取方式再最下方 java计算机毕设课设—商品供应管理系统(附源码、文章、相关截图、部署视频) 项目名称&#xff1a; 基于Java的商品供应管理系统 一、项目介绍 项目背景&#xff1a; 在现代商业活动中&#xff0c;商品供应管理是企业运营的…

ipad如何直连主机(Moonlight Sunshine)

Windows 被连接主机&#xff08;Windows&#xff09; 要使用的话需要固定ip&#xff0c;不然ip会换来换去&#xff0c;固定ip方法本人博客有记载Github下载Sunshine Sunshine下载地址除了安装路径需要改一下&#xff0c;其他一路点安装完成后会打开Sunshine的Web UI&#xff…

B站推荐模型数据流的一致性架构

01 背景 推荐系统的模型&#xff0c;通过学习用户历史行为来达到个性化精准推荐的目的&#xff0c;因此模型训练依赖的样本数据&#xff0c;需要包括用户特征、服务端推荐的视频特征&#xff0c;以及用户在推荐视频上是否有一系列的消费行为。 推荐模型数据流&#xff0c;即为…

快速掌握Haproxy原理架构

文章目录 一、原理架构二、无负载均衡三、四层负载均衡的工作流程四、七层负载均衡工作流程五、基础属性mode 属性retries 属性maxconn 属性clitimeout 属性servtimeout 属性states uri 属性 一、原理架构 四层tcp代理&#xff1a;Haproxy仅在客户端和服务器之间双向转发流量&…

Pytest基础01: 入门demo脚本

目录 1 Pytest接口测试 1.1 最简单版hello world 1.2 pytest.ini 2 pytest兼容unittest 3 封装pytest执行入口 1 Pytest接口测试 Pyest是一个可以用于接口测试的强大框架&#xff0c;开源社区也有非常多的pytest插件。 按江湖传统&#xff0c;学习一个新语言或者新框架&…

《HelloGitHub》第 105 期

兴趣是最好的老师&#xff0c;HelloGitHub 让你对编程感兴趣&#xff01; 简介 HelloGitHub 分享 GitHub 上有趣、入门级的开源项目。 github.com/521xueweihan/HelloGitHub 这里有实战项目、入门教程、黑科技、开源书籍、大厂开源项目等&#xff0c;涵盖多种编程语言 Python、…

Linux day 1129

家人们今天继续学习Linux&#xff0c;ok话不多说一起去看看吧 三.Linux常用命令 3.1 Linux命令体验 3.1.1 常用命令演示 在这一部分中&#xff0c;我们主要介绍几个常用的命令&#xff0c;让大家快速感 受以下 Linux 指令的操作方式。主要包含以下几个指令&#xff1a; ls命…

python爬虫爬抖音小店商品数据+数据可视化

爬虫代码 爬虫代码是我调用的数据接口&#xff0c;可能会过一段时间用不了&#xff0c;欢迎大家留言评论&#xff0c;我会不定时更新 import requests import time cookies {token: 5549EB98B15E411DA0BD05935C0F225F,tfstk: g1vopsc0sQ5SwD8TyEWSTmONZ3cA2u6CReedJ9QEgZ7byz…