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

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

插件优点:

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

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

cpp 复制代码
#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文件

cpp 复制代码
#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窗口,创建其实例

cpp 复制代码
#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文件,放在头文件同目录

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

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

将qt插件功能启动

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

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

cpp 复制代码
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;
}
相关推荐
迷失蒲公英24 分钟前
XML与Go结构互转实现(序列化及反序列化)
xml·开发语言·golang
测试盐1 小时前
c++编译过程初识
开发语言·c++
赖赖赖先生1 小时前
fastadmin 框架 生成qr code 二维码图片,PHP 7.4版本
开发语言·php
玉红7772 小时前
R语言的数据类型
开发语言·后端·golang
夜斗(dou)2 小时前
node.js文件压缩包解析,反馈解析进度,解析后的文件字节正常
开发语言·javascript·node.js
觅远2 小时前
python+PyMuPDF库:(一)创建pdf文件及内容读取和写入
开发语言·python·pdf
神雕杨2 小时前
node js 过滤空白行
开发语言·前端·javascript
lvbu_2024war013 小时前
MATLAB语言的网络编程
开发语言·后端·golang
single5943 小时前
【c++笔试强训】(第四十五篇)
java·开发语言·数据结构·c++·算法
游客5203 小时前
自动化办公-合并多个excel
开发语言·python·自动化·excel