123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655 |
- #pragma once
- #include <QString>
- #include <QVector>
- #include <QWidget>
- #include <QDialog>
- #include <QMessageBox>
- #include <QCoreApplication>
- #include <QBuffer>
- #include <QCloseEvent>
- #include "VisionPlus.h"
- #include "VisionPlusToolUtility.h"
- // 使用 utf8 编码
- #if _MSC_VER >= 1600
- #pragma execution_character_set("utf-8")
- #endif
- // 自定义警告信息
- #define vDebug() qDebug() << "[" << __FUNCTION__ << ":" << __LINE__ << "]"
- #define vWarning() qWarning() << "[" << __FUNCTION__ << ":" << __LINE__ << "]"
- // dll 通用接口函数名称
- // 获取工具函数的指针
- #define FUNCTION_GETTOOL ("GetTool")
- // 释放工具函数的指针
- #define FUNCTION_RELEASETOOL ("ReleaseTool")
- //////////////////////////////////////////////
- // Dll工具的描述信息
- typedef struct _tagDllToolDescription
- {
- TOOL_TYPE Type; // 工具的类型(工具、控件、跳转指令)
- QString strCategory; // 工具的分组
- QString strName; // 工具名字
- QString strAliasName; // 工具别名(通常为曾用名或者中文名)
- QString strVersion; // 工具版本
- QString strInfo; // 描述信息
- _tagDllToolDescription()
- {
- Type = TOOL_TYPE::TOOL_TYPE_STANDARD;
- }
- } DLL_TOOL_DESC, * LPDLL_TOOL_DESC;
- // dll消息向exe同步的回调函数(控件类型,已经废弃,统一和value类型一样采用postEvent了)
- // QWidget: 触发消息的控件指针
- // MSG: 触发的消息
- typedef std::function<void(QWidget*, UI_SYNC_MSG msg)> CONTROL_CALLBACK;
- //// dll数值向exe同步的回调函数(数值类型,由于影响Tool的Execute的效率,已经废弃,改为postEvent的方式)
- //typedef std::function<void(void* value, VALUE_TYPE type)> VALUE_CALLBACK;
- //////////////////////////////////////////////////////////
- // 工具中的对话框信息封装类(PORT类型工具没有对话框界面)
- class DllToolDialog : public QDialog
- {
- public:
- DllToolDialog(QWidget* parent = nullptr) :
- QDialog(parent),
- m_pEventTarget(nullptr),
- m_pSyncTarget(nullptr),
- m_pGvlTarget(nullptr),
- m_pDB(nullptr),
- controlCallback(nullptr),
- m_pPouTarget(nullptr)
- {
- };
- virtual ~DllToolDialog() {};
- public:
- virtual VPEnum::RETURN_VALUE Execute() { return VPEnum::RETURN_VALUE::Success; };
- virtual void Running(bool bRun) { Q_UNUSED(bRun); };
- virtual bool updateValue(int nIndex) { Q_UNUSED(nIndex); return true; };
- // 设置Event类型工具的事件接收对象(exe中的TaskManager)
- virtual void setEventTarget(QObject* pTarget)
- {
- this->m_pEventTarget = pTarget;
- }
- // 设置变量和控件同步事件的接收对象(exe中的WindowRunTime)
- virtual void setSyncTarget(QObject* pTarget)
- {
- this->m_pSyncTarget = pTarget;
- }
- // 设置全局变量操作指针,用于接收变量变动通知消息(exe中GvlManager)
- virtual void setGvlTarget(QObject* pTarget)
- {
- this->m_pGvlTarget = pTarget;
- }
- // 设置Pou管理者指针,用于接收接口变动通知消息(exe中的WindowAppPouScene)
- virtual void setPouTarget(QObject* pTarget)
- {
- this->m_pPouTarget = pTarget;
- }
- virtual bool Serialized(QDataStream& ar, bool bIsOut)
- {
- Q_UNUSED(ar);
- Q_UNUSED(bIsOut);
- return true;
- }
- // 设置控件双向同步的回调函数
- void setControlCallback(CONTROL_CALLBACK callback)
- {
- this->controlCallback = callback;
- }
- // 设置绑定的DB变量(仅硬件工具有可能会用到)
- void setBindDB(GVL* pDB)
- {
- this->m_pDB = pDB;
- }
- // 解除DB的绑定(仅硬件工具有可能会用到)
- void unbindDB()
- {
- this->m_pDB = nullptr;
- }
- //// 设置数值变更向UI单向同步的回调函数
- //void setValueCallback(VALUE_CALLBACK callback)
- //{
- // this->valueCallback = callback;
- //}
- // 变动的硬件数值向UI同步(第一种方式,按接口全名称同步,主要用于硬件组态的接口数值同步,因为硬件组态的数值没有Execute)
- void syncHdValueToUi(QString strInstanceName, QString strInfName)
- {
- if (this->m_pSyncTarget == nullptr)
- {
- // qDebug() << "ToolDialogImpl::syncValueToUi failed - m_pSyncTarget is nullptr.";
- return;
- }
- // 生成数值同步消息,向UI同步
- SyncHdValueEvent* valueEvent = new SyncHdValueEvent();
- valueEvent->setGroupName(m_strPouName);
- // 保存变动数值信息
- valueEvent->m_strInstanceName = strInstanceName;
- valueEvent->m_strInfName = strInfName;
- // 发送 value 同步 event,event指针会自动释放
- QCoreApplication::postEvent(m_pSyncTarget, valueEvent);
- }
- // 变动的硬件数值向UI同步(第二种方式,按接口指针同步,主要用于硬件组态的接口数值同步,因为硬件组态的数值没有Execute)
- void syncHdValueToUi(void* pValue)
- {
- if (this->m_pSyncTarget == nullptr)
- {
- // qDebug() << "ToolDialogImpl::syncValueToUi failed - m_pSyncTarget is nullptr.";
- return;
- }
- // 生成数值同步消息,向UI同步
- SyncHdValueEvent* valueEvent = new SyncHdValueEvent();
- // 保存变动数值信息
- valueEvent->m_pSrcValue = pValue;
- // 发送 value 同步 event,event指针会自动释放
- QCoreApplication::postEvent(m_pSyncTarget, valueEvent);
- }
- // 变动的控件向UI同步
- void syncControlToUi(QWidget* pWidget, UI_SYNC_MSG syncMsg)
- {
- if (this->m_pSyncTarget == nullptr)
- {
- qDebug() << "ToolDialogImpl::syncControlToUi failed - m_pSyncTarget is nullptr.";
- return;
- }
- // 生成控件的同步消息,向UI同步
- SyncControlEvent* controlEvent = new SyncControlEvent();
- // 保存变动数值信息
- controlEvent->m_pSrcControl = pWidget;
- controlEvent->m_SyncMsg = syncMsg;
- // 发送 value 同步 event,event指针会自动释放
- QCoreApplication::postEvent(m_pSyncTarget, controlEvent);
- }
- DebugData GetDebugData()
- {
- return m_DebugData;
- }
- void SetDebugData(DebugData data)
- {
- m_DebugData = data;
- }
- DebugData* GetDebugDataPtr()
- {
- return &m_DebugData;
- }
- void SetToolInfo(QString strPouName, QString strInstanceName)
- {
- m_strPouName = strPouName;
- m_strInstanceName = strInstanceName;
- }
- void showEvent(QShowEvent* event)
- {
- Q_UNUSED(event);
- // 将本工具的数据备份一下,以便误操作的时候,使用取消按钮恢复数据
- try
- {
- m_BufferBackup.open(QIODevice::WriteOnly);
- QDataStream ar(&m_BufferBackup);
- this->Serialized(ar, true);
- m_BufferBackup.close();
- }
- catch (HalconCpp::HException& ex)
- {
- QString hErr = Utility::getHalconErrMessage(ex.ErrorCode());
- }
- catch (...)
- {
- qWarning() << "Backup To Buffer Error";
- }
- }
- void closeEvent(QCloseEvent* event)
- {
- event->ignore();
- this->hide();
- }
- bool RecoverData()
- {
- try
- {
- m_BufferBackup.open(QIODevice::ReadOnly);
- QDataStream ar(&m_BufferBackup);
- this->Serialized(ar, false);
- m_BufferBackup.close();
- this->hide();
- }
- catch (...)
- {
- qWarning() << "Load Frm Buffer Error";
- return false;
- }
- return true;
- }
- protected:
- // Event Target(TaskManager*)
- QObject* m_pEventTarget;
- // Sync Target(WindowRunTime*)
- QObject* m_pSyncTarget;
- // 用于接收数值变动通知的指针(GvlManager*)
- QObject* m_pGvlTarget;
- // 用于接收接口变动通知的指针(WindowAppPouScene*)
- QObject* m_pPouTarget;
- // 2022-3-1,本工具所绑定的DB变量组指针
- GVL* m_pDB;
- // 控件用于双向同步的回调函数
- CONTROL_CALLBACK controlCallback;
- //// 用于数值变更后向界面同步的回调函数
- //VALUE_CALLBACK valueCallback;
- DebugData m_DebugData;
- // 本工具的实例名字
- QString m_strInstanceName;
- // 本工具所在的Pou名字
- QString m_strPouName;
- //用于备份数据的buffer
- QBuffer m_BufferBackup;
- };
- //////////////////////////////////////////////////////////
- // 工具信息的封装类
- class DllTool
- {
- public:
- DllTool()
- {
- ////ControlCallback = nullptr;
- //m_Even.hEvenHandle = nullptr;
- //m_Even.nEvenTime = 0;
- m_pDlgTool = nullptr;
- }
- virtual ~DllTool()
- {
- }
- public:
- // 执行工具
- virtual VPEnum::RETURN_VALUE Execute()
- {
- if (m_pDlgTool != nullptr)
- {
- return m_pDlgTool->Execute();
- }
- return VPEnum::RETURN_VALUE::Error;
- }
- //系统Run和Stop时调用
- virtual void Running(bool bRun)
- {
- if (m_pDlgTool != nullptr)
- {
- m_pDlgTool->Running(bRun);
- }
- }
- //
- virtual bool updateValue(int nIndex)
- {
- if (m_pDlgTool != nullptr)
- {
- return m_pDlgTool->updateValue(nIndex);
- }
- return false;
- }
- // 显示参数设置对话框
- virtual void ShowDialog()
- {
- if (m_pDlgTool != nullptr)
- {
- m_pDlgTool->show();
- m_pDlgTool->setWindowTitle(this->m_strPouName + (" ---> ") + this->m_strInstanceName);
- }
- }
- // 获取调试参数
- virtual DebugData GetDebugData()
- {
- if (m_pDlgTool != nullptr)
- {
- return m_pDlgTool->GetDebugData();
- }
- DebugData data;
- return data;
- }
- // 2022-10-4增加,Dll信息中保存一下本Dll对应的全路径,用于后续查询
- QString m_strFullPath;
- public:
- /// <summary>
- /// 工具初始化(不带参数)
- /// </summary>
- virtual int InitTool() = 0;
- /// <summary>
- /// 纯虚函数,工具初始化
- /// </summary>
- /// <param name="pWnd">父窗体指针</param>
- /// <param name="strPouName">工具所在Pou的名字</param>
- /// <param name="strInstanceName">工具生成的实例名字</param>
- /// <returns></returns>
- virtual int InitTool(QWidget* pWnd, QString strPouName, QString strInstanceName, QObject* pEventTarget = nullptr) = 0;
- /// <summary>
- /// 获取工具的总体描述信息
- /// </summary>
- virtual const DLL_TOOL_DESC& Description() = 0;
- virtual bool bindValuePtrByName(const QString strName, const int nIndex) = 0;
- /// <summary>
- /// 获取本工具的名称
- /// </summary>
- /// <returns></returns>
- QString getName()
- {
- return this->m_strPouName;
- }
- /// <summary>
- /// 获取本工具的实例名称
- /// </summary>
- /// <returns></returns>
- QString getInstanceName()
- {
- return this->m_strInstanceName;
- }
- /// <summary>
- /// 序列化至文件
- /// </summary>
- virtual bool SerializedToDoc(QDataStream& out) { Q_UNUSED(out); return true; }
- /// <summary>
- /// 从文件反序列化
- /// </summary>
- virtual bool SerializedFromDoc(QDataStream& in) { Q_UNUSED(in); return true; }
- // 修改所在的Pou名字
- void ModToolPouName(QString strNewPouName)
- {
- this->m_strPouName = strNewPouName;
- if (m_pDlgTool != nullptr)
- {
- m_pDlgTool->SetToolInfo(m_strPouName, m_strInstanceName);
- }
- }
- // 修改工具的实例名字
- void ModToolInstanceName(QString strNewInstanceName)
- {
- this->m_strInstanceName = strNewInstanceName;
- if (m_pDlgTool != nullptr)
- {
- m_pDlgTool->SetToolInfo(m_strPouName, m_strInstanceName);
- }
- }
- // 获取指定的接口
- DLL_INF& Interface(const int nIndex)
- {
- return m_Interfaces[nIndex];
- }
- // 获取工具接口的数量
- int GetInterfaceSize()
- {
- return m_Interfaces.size();
- }
- // 动态增加接口
- virtual void AddInterface(const DLL_INF& dll_inf)
- {
- m_Interfaces.push_back(dll_inf);
- };
- // 动态删除接口
- virtual bool DelInterface(const QString& infName)
- {
- bool bFind = false;
- for (int i = 0; i < m_Interfaces.size(); i++)
- {
- DLL_INF& dllInf = m_Interfaces[i];
- if (dllInf.strName == infName)
- {
- // 只有动态接口才允许删除
- if (!dllInf.bDynamic)
- {
- qDebug() << "DllTool::DelInterface - failed, reason: " << dllInf.strName << " is not dynamic interface.";
- return false;
- }
- m_Interfaces.removeAt(i);
- bFind = true;
- }
- // 后续的接口Index都需要 - 1
- else
- {
- dllInf.nIndex--;
- }
- }
- return bFind;
- }
- // 获取工具接口的值
- template<typename T>
- T& Value(const int nIndex)
- {
- if (m_Interfaces.size() <= nIndex)
- {
- qWarning() << "DllTool::Value() Error - Inf Size:[" << m_Interfaces.size() << "] Index Vilue: [" << nIndex << "]";
- }
- return *(T*)m_Interfaces[nIndex].value.Ptr;
- }
- // 设置Interface的值(默认绑定成员变量,不重新开辟内存)
- template<typename T>
- void SetValue(const int nIndex, T& t)
- {
- if (m_Interfaces.size() <= nIndex)
- {
- qWarning() << "DllTool::SetValue() Error - Inf Size:[" << m_Interfaces.size() << "] Index Vilue: [" << nIndex << "]";
- return;
- }
- this->SetValue(m_Interfaces[nIndex].value, t);
- }
- // 设置Interface的值(默认绑定成员变量,不重新开辟内存)
- template<typename T>
- void SetValue(VALUE& value, T& t)
- {
- value.Ptr = (void**)&t;
- }
- // 更新Interface的值(已经开辟好了内存,只是做值的更新)
- template<typename T>
- void UpdateValue(const int nIndex, T& t, VALUE_PASS_MODE passmode = VALUE_PASS_MODE::PASS_BY_VALUE)
- {
- if (m_Interfaces.size() <= nIndex)
- {
- qWarning() << "DllTool::UpdateValue() Error - Inf Size:[" << m_Interfaces.size() << "] Index Vilue: [" << nIndex << "]";
- return;
- }
- // 按值
- if (passmode == VALUE_PASS_MODE::PASS_BY_VALUE)
- {
- *(T*)m_Interfaces[nIndex].value.Ptr = t;
- }
- // 按地址
- else
- {
- *m_Interfaces[nIndex].value.Ptr = &t;
- }
- }
- // 设置Event类型工具的事件接收对象(exe中的TaskManager)
- void setEventTarget(QObject* pTarget) const
- {
- Q_ASSERT(pTarget != nullptr);
- if (m_pDlgTool)
- {
- this->m_pDlgTool->setEventTarget(pTarget);
- }
- }
- // 设置变量和控件同步事件的接收对象(exe中的WindowRuntime*)
- void setSyncTarget(QObject* pTarget) const
- {
- Q_ASSERT(pTarget != nullptr);
- if (m_pDlgTool)
- {
- this->m_pDlgTool->setSyncTarget(pTarget);
- }
- }
- // 设置全局变量操作指针,用于接收变量变动通知消息(exe中GvlManager)
- void setGvlTarget(QObject* pTarget)
- {
- Q_ASSERT(pTarget != nullptr);
- if (m_pDlgTool)
- {
- this->m_pDlgTool->setGvlTarget(pTarget);
- }
- }
- // 设置Pou管理者指针,用于接收接口变动通知消息(exe中的WindowAppPouScene)
- void setPouTarget(QObject* pTarget)
- {
- Q_ASSERT(pTarget != nullptr);
- if (m_pDlgTool)
- {
- this->m_pDlgTool->setPouTarget(pTarget);
- }
- }
- // 设置控件双向同步的回调函数
- void setControlCallback(CONTROL_CALLBACK callback)
- {
- if (m_pDlgTool)
- {
- this->m_pDlgTool->setControlCallback(callback);
- }
- }
- // 设置绑定的DB变量(仅硬件工具有可能会用到)
- void setBindDB(GVL* pDB)
- {
- Q_ASSERT(pDB != nullptr);
- this->m_pDlgTool->setBindDB(pDB);
- }
- // 解除绑定的DB变量(仅硬件工具有可能会用到)
- void unbindDB()
- {
- this->m_pDlgTool->unbindDB();
- }
- //// 设置数值向UI同步的回调函数
- //void setValueCallback(VALUE_CALLBACK callback)
- //{
- // this->m_pDlgTool->setValueCallback(callback);
- //}
- protected:
- // 初始化默认的接口描述
- virtual void InitDefaultInterfaces(bool withValue = false) = 0;
- protected:
- // 本工具的接口
- QVector<DLL_INF> m_Interfaces;
- // 本工具的对话框
- DllToolDialog* m_pDlgTool;
- // 本工具的实例名字
- QString m_strInstanceName;
- // 本工具所在的Pou名字
- QString m_strPouName;
- };
|