许可优化
许可优化
产品
产品
解决方案
解决方案
服务支持
服务支持
关于
关于
软件库
当前位置:服务支持 >  软件文章 >  NX二次开发 调用Qt界面的方法

NX二次开发 调用Qt界面的方法

阅读数 4
点赞 0
article_banner

前言:

NX  调用Qt界面是可行的,相对麻烦些


注意:

1. NX软件本身内置了QT库,所以调用第三方QT开发时,必须保证版本统一,否则会报错:

后面重新测试,QT5.12.0,QT5.12.7都是可行的,QT环境通过环境变量

set QT_PLUGIN_PATH=%WORK_DIR%\plugins 设置,QT官方解释:

https://doc.qt.io/qt-6/deployment-plugins.html

2. 项目类型不是NX项目,而是创建Qt Widgets Application 项目,然后配置NX相关环境配置,

(也可以建立普通的C++ 项目,然后把NX和QT相关头文件库包含进去,QT项目容易出错)

3. 关于QT dll打包,和QT exe程序打包是不一样的,

不能用windeployqt命令来收集

不能用windeployqt命令来收集

不能用windeployqt命令来收集

收集的dll和QT bin目录下的dll是不一样的!!!如果收集的dll不对,后续环境变量的设置都是无效的,必须从bin目录下拷贝dll。


环境:

Win10, VS2017  ,NX1899,Qt5.12.X


项目搭建设置使用:

1.使用VS2017创建项目,注意是创建Qt项目,不是NX项目。一直下一步即可

2. 项目属性配置:

(1)设置类型改成动态库dll(MFC的使用和字符集没有测试过,使用的默认值)

(2)设置 附加包含目录、附加库目录、附加依赖项

注意:有时候虽然配置成dll,但仍然生成exe文件,此时需要强制更改输出文件

3. 编码  

参考链接: https://github.com/Alexpux/qt-solutions/archive/refs/heads/master.zip

(1)从GitHub项目上摘取 qmfcapp.h  qmfcapp. cpp  qwinwidget.h   qwinwidget.cpp,添加到项目

(2)打开main.cpp文件,删除main函数,添加NX 入口函数:ufusr、ufusr_ask_unload:

#include <qmfcapp.h>#include <qwinwidget.h>#include <QMessageBox>#include <afx.h>#include <afxwin.h>#include <Windows.h>#include <QtGui.h>#include <uf.h>#include <uf_ui.h> BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpvReserved){    static bool ownApplication = FALSE;     //内部创建application实例    if (dwReason == DLL_PROCESS_ATTACH)    {        ownApplication = QMfcApp::pluginInstance(hInstance);         //qApp 相关设置    }     //退出的时候delete qApp;    if (dwReason == DLL_PROCESS_DETACH && ownApplication)    {        delete qApp;    }     return TRUE;} extern "C" DllExport void ufusr(char *param, int *retcod, int param_len){    if (UF_initialize())    {        return;    }     HWND hwnd = (HWND)UF_UI_get_default_parent();    QWinWidget* parent = new QWinWidget(hwnd);     //这里必须是指针,否则无效    //QtGui gui(qWinWidget);    //gui.activateWindow();    //gui.show();    QtGui* gui = new QtGui(parent);    gui->activateWindow();    gui->show();     UF_terminate();} extern "C" DllExport int ufusr_ask_unload(){    return (UF_UNLOAD_UG_TERMINATE);}

需要注意的是:将父窗口转成这个类QWinWidget,然后作为parent 传入自定义对话框类中。

不能将自定义对话框直接继承QWinWidget

其他测试代码:

QtGui.hpp

#pragma once #include <QtWidgets/QMainWindow>#include <qwinwidget.h>#include <QWidget>#include <QLabel>#include <QGridLayout>#include <QLineEdit>#include <QCheckBox>#include <QDialog>#include <QPushButton>  class QtGui : public QDialog{    Q_OBJECT public:    QtGui(QWidget* parent); public slots:    void CreateBlock(); private:    QLabel* m_lengthLabel;    QLineEdit* m_lengthLineEdit;    QLabel* m_widthLabel;    QLineEdit* m_widthLineEdit;    QLabel* m_heightLabel;    QLineEdit* m_heightLineEdit;    QPushButton* m_createBlock;    QGridLayout* m_mainLayout; }; 

QtGui.cpp

#pragma execution_character_set("utf-8")#include "QtGui.h"#include <uf_modl.h> QtGui::QtGui(QWidget* parent) :QDialog(parent){    m_lengthLabel = new QLabel(tr("长度:"));    m_lengthLineEdit = new QLineEdit;     m_widthLabel = new QLabel(tr("宽度:"));    m_widthLineEdit = new QLineEdit;     m_heightLabel = new QLabel(tr("高度:"));    m_heightLineEdit = new QLineEdit;     m_createBlock = new QPushButton(tr("创建块"));     m_mainLayout = new QGridLayout(this);    m_mainLayout->setMargin(15);    m_mainLayout->setSpacing(10);     m_mainLayout->addWidget(m_lengthLabel, 0, 0);    m_mainLayout->addWidget(m_lengthLineEdit, 0, 1);    m_mainLayout->addWidget(m_widthLabel, 1, 0);    m_mainLayout->addWidget(m_widthLineEdit, 1, 1);    m_mainLayout->addWidget(m_heightLabel, 2, 0);    m_mainLayout->addWidget(m_heightLineEdit, 2, 1);    m_mainLayout->addWidget(m_createBlock, 3, 0);    m_mainLayout->setSizeConstraint(QLayout::SetFixedSize);     connect(m_createBlock, &QPushButton::clicked, this, &QtGui::CreateBlock);} void QtGui::CreateBlock(){    std::string length = m_lengthLineEdit->text().toStdString();    std::string width = m_widthLineEdit->text().toStdString();    std::string height = m_heightLineEdit->text().toStdString();     double corner[3] = { 0.0 };    char* size[3] = { const_cast<char*>(length.c_str()),                              const_cast<char*>(width.c_str()),                              const_cast<char*>(height.c_str())                             };     tag_t blockFeat = NULL_TAG;    UF_MODL_create_block(UF_FEATURE_SIGN::UF_NULLSIGN, NULL_TAG, corner, size, &blockFeat);    UF_MODL_update();}

(3)示例:创建一个块


4. 收集依赖的dll

开发时配置QT环境到PATH中,启动VS编译运行都是OK的

@echo offset WORK_DIR=https://www.gofarlic.com\MyProject\Qt\Qt_NX\QtClassLibrary1set "UGII_BASE_DIR=C:\Program Files\Siemens\NX1899"set VS2017_EXE="C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\Common7\IDE\devenv.exe"set QTDIR=C:\Qt\Qt5.12.7\5.12.7\msvc2017_64 rem set PATH=%UGII_ROOT_DIR%;%UGII_UGRAF_DIR%;%PATH%;%QTDIR%\bin;set UGII_DISPLAY_DEBUG=1 %VS2017_EXE%  %WORK_DIR%\QtClassLibrary1.sln

但按照之前的用windeployqt命令来收集好dll之后会报错,只要运行NX界面上的属性、信息功能或者调用API UF_UI_write_listing_window() 功就会崩溃......

尝试过set QT_QPA_PLATFORM_PLUGIN_PATH到 dll所在文件夹也不行,各种报错:

最后从把所有bin文件夹下的内容拷贝到dll所在目录,然后NX中调用这个dll,再把拷贝的文件全部删除,看哪些dll被占用,发现:

然后只保留这三个dll文件,就可以了 !!!

(编译的dll是Release版本,如果是Debug,依赖的三个dll要加d)


5. 部署到其他电脑使用

本来以为收集3个dll就结束了,然后把软件包拷贝到其他电脑上使用,结果报错:

百度搜了下:可以参考链接:

https://blog.csdn.net/qq_43903004/article/details/113878306

https://blog.csdn.net/qq_51606180/article/details/120384845

set QT_PLUGIN_PATH=%WORK_DIR%\plugins 或

   set QT_QPA_PLATFORM_PLUGIN_PATH=%WORK_DIR%\plugins\platforms

运行成功,还是得通过报错信息上找原因。


免责声明:本文系网络转载或改编,未找到原创作者,版权归原作者所有。如涉及版权,请联系删

相关文章
技术文档
QR Code
微信扫一扫,欢迎咨询~
customer

online

联系我们
武汉格发信息技术有限公司
湖北省武汉市经开区科技园西路6号103孵化器
电话:155-2731-8020 座机:027-59821821
邮件:tanzw@gofarlic.com
Copyright © 2023 Gofarsoft Co.,Ltd. 保留所有权利
遇到许可问题?该如何解决!?
评估许可证实际采购量? 
不清楚软件许可证使用数据? 
收到软件厂商律师函!?  
想要少购买点许可证,节省费用? 
收到软件厂商侵权通告!?  
有正版license,但许可证不够用,需要新购? 
联系方式 board-phone 155-2731-8020
close1
预留信息,一起解决您的问题
* 姓名:
* 手机:

* 公司名称:

姓名不为空

姓名不为空

姓名不为空
手机不正确

手机不正确

手机不正确
公司不为空

公司不为空

公司不为空