一般来说,同一项目下,是不太会出现同时使用qml和ui两种方式来编写界面的,但是,实际开发中,总是会遇到各种意外的情况和需求。比如两个不同软件的合并。下面将介绍两种qml和ui界面的结合方式。
qml对ui界面的调用,主要是获取qml界面的句柄,然后赋给需要调用的ui界面,再在qml中需要的地方开一个控件,用来加载修改过句柄的ui界面。具体代码如下:
//在main.cpp里加上:
QQmlApplicationEngine *engine;
engine = new QQmlApplicationEngine();
engine->load(QUrl(QStringLiteral("qrc:/main.qml")));
QObject *QmlObj = engine->rootObjects().first(); //获取QMl的源对象
QWindow *QmlWindow = qobject_cast<QWindow *>(QmlObj);//获取qml在的源窗口
WId parent_HWND = QmlWindow->winId(); //Qml窗口的句柄
NewRobotPlant Widget; //需要在qml中加载的带ui的界面类,继承于QWidget
Widget.setProperty("_q_embedded_native_parent_handle",QVariant(parent_HWND));//给widget父对象句柄赋值
Widget.winId();//必须调用,才能为widget创建句柄,否则将会失败
Widget.windowHandle()->setParent(QmlWindow);//同样是设置父窗口
这里的qml引擎engine一般都是指向main.qml,不用多说。之后代码,可以获取到qml界面的窗口句柄,用来修改这里初始化建立的需要加载的ui界面类的句柄,之后就是在qml中调用,这里我就不贴代码了,因为每个人的调用方式不一定一样,我就讲一下自己的调用方式:
———我的qml结构,是只有一个window的,通过切换该window加载的url来实现不同界面的显示。
———所以我单独开了一个空白的url,用来加载该ui界面,在main.qml中切换到该url时,发出信号
———在c++中接收该信号,并与 Widget 的 show() 函数建立connect,该Wideget可以直接show出来
在ui界面中调用qml,其实更加简单一点,只需要单独拿一个控件出来用来显示qml的界面即可,但需要注意的是,在main.qml和main.cpp同时存在的情况下,如果单纯地复制原qml软件中的main.cpp代码到ui软件的main.cpp之中,即使运行起来,也会同时开启ui和qml两个软件。所以在ui中调用qml,需要重新处理main函数的结构。下面是代码:
//main.cpp中的代码:
//一般qt建立的ui软件,上面还会有QCoreApplication和QGuiApplication,直接进注释即可
QApplication a(argc, argv);
//这里不需要qml的main.cpp中的其他代码,包括qml引擎engine之类的,全不需要,只需要保留:
//*******图标库的添加代码(如果你的qml中用到了)
//*******注册表Setting的设置代码(如果你的qml中用到了)
//*******c++中类属性注册到qml中的注册代码(一般有信息交互的都会用到)
//下面的代码,加到你需要加载qml界面的类的构造函数里即可。
QUrl source("qrc:/qml/Maindebug.qml"); //需要加载的qml界面
//QQuickWidget用来加载qml界面的ui控件
ui->quickWidget->setResizeMode(QQuickWidget::SizeRootObjectToView );
ui->quickWidget->setSource(source);
ui->quickWidget->setClearColor(QColor(Qt::transparent));
QQuickItem *mainDebug = ui->quickWidget->rootObject(); //指向qml界面内成员的指针
上面的代码,就是用一个QQuickWidget控件来加载qml界面的方法,不需要引擎engine这些东西,只需要一个url即可。
注意一点,最后一行是一个类似 root 的指针,指向加载的qml界面,可以通过这个指针去 findchild 你需要的各个qml界面中的控件或者信号。
一般qt的软件发布,都会用qt控制台自带的windeployqt命令去寻找依赖库,有时候找的全,有时候找不全,但一般来说,只要补全外部库,qt自带的内部库,是可以给你找全的。但是,一旦加了qml之后,基本是找不全的,连自己的内部库都找不全,也是真的无语,反正我带qml的项目,用windeployqt去找,最后一般运行不起来,运气好运行起来,qml界面也是黑的。
所以,发布qml软件的最好方式就是:拷贝你release编译目录下的exe文件到一个空文件夹里,再拷贝qt安装目录下(…:\qt5.13.2\5.13.2\msvc2015_64),bin文件夹、plugins文件夹以及qml文件夹里的全部文件到该文件夹下,删光debug库文件(就是名字最好一个字母是d的dll文件),再把你添加的外部库也全部考进来,用 inno打包,这样是可以发布运行的,或许会加上很多没必要的库,但是我实在懒得一个个找了,你们有什么好方法,底下留个言可好。