QML动态创建自定义组件
一、动态加载和实例化对象:createComponent
例子1:
①、创建本地的QML文件,注意文件第一个字母要大写
ZStation.qml
import QtQuick 2.5 Rectangle{ property string mName: "station" signal entered(string objName); signal exited(); property int station_width: width/3 id: root color: Qt.rgba(0,0,0,0) width: 90 height: width/3 Rectangle{ id: station color:"green" width: station_width height: width radius: width/2 } Text { anchors.top:parent.top; anchors.left: station.right; anchors.leftMargin: 5; width: 30 height: 12 text: mName color: "white" } MouseArea { hoverEnabled: true; anchors.fill: parent; onEntered: { root.entered(root.objectName); } onExited: { root.exited(); } } }
②、在主qml里动态创建并连接信号槽
function addStation(x, y, id, name){ console.log(x,y,id,name); var componentIn = Qt.createComponent("ZStation.qml"); if (componentIn.status === Component.Ready) { var objIn = componentIn.createObject(root, {"mName":name, "objectName":id}); if(auto_scale){ x = getNearX(x); y = getNearY(y); } objIn.x = x; objIn.y = y; objIn.entered.connect(root.showPopInfo) objIn.exited.connect(root.hidePopInfo) station_list.push(objIn); console.log(x,y); }else{ console.log("qml create station err:",componentIn.errorString()); } }
例子2:
①、main.qml
import QtQuick 2.9 import QtQuick.Window 2.2 Window { id: mainWin visible: true width: 640 height: 480 title: qsTr("Hello World") LoginPage { width: 300 height: 200 anchors.centerIn: parent } }
②、LoginPage.qml
import QtQuick 2.0 import QtQuick.Controls 2.3 Rectangle { id: loginPage width: 400 height: 300 color: "#051f58" radius: 8 clip:true Button { text: "登录页面-登录按钮" anchors.centerIn: parent onClicked: { // 隐藏登录页面 loginPage.visible = false // 不能销毁,否则下面的"主页面"也会跟随销毁,则后面 // 点击"主页面-关闭按钮",将无法销毁关闭"主页面" // 在主窗口(mainWin)上显示主页面 var compMainPage = Qt.createComponent("MainPage.qml") .createObject(mainWin, {x:50, y:50, width:200, height:250}); } } }
③、MainPage.qml
import QtQuick 2.0 import QtQuick.Controls 2.3 Rectangle { id: mainPage color: "#498ff8" radius: 8 Button { text: "主页面-关闭按钮" anchors.centerIn: parent onClicked: { // 销毁关闭主页面 mainPage.destroy() } } }
参考:https://www.cnblogs.com/linuxAndMcu/p/13566502.html
PS:
①、createComponent的返回值
②、创建过程时间是不确定的,我们上面的例子都是直接创建并判断状态,大多数情况是没问题,但是遇到特殊情况如:加载多种依赖或位于缓慢服务器中的QML时,会很慢【而且貌似创建函数不会阻塞】,故正确做法是:加一个判断
function createImageObject() { component = Qt.createComponent("dynamic-image.qml"); if (component.status === Component.Ready || component.status === Component.Error) { finishCreation(); } else { component.statusChanged.connect(finishCreation); } } function finishCreation() { if (component.status === Component.Ready) { var image = component.createObject(root, {"x": 100, "y": 100}); if (image === null) { console.log("Error creating image"); } } else if (component.status === Component.Error) { console.log("Error loading component:", component.errorString()); } }
例子位于QMLBook的第15章节,动态创建组件。
③、销毁
item=Qt.createQmlObject(...);
...
item.destroy();
二、动态创建Component
这个方式和上面原理一致,component1是事先定义好的Component
Component.onCompleted: { var obj1 = component1.createObject(root, { "color": "red", "width": 100, "height": 100}) var obj2 = component2.createObject(root, { "color": "green", "width": 200, "height": 200}) var obj3 = component3.createObject(root, { "color": "gray", "width": 300, "height": 300}) }
三、从文本文件动态实例化:createQmlObject
1、接口
qml:qml文本
parent:对象的父亲
filepath:存储创建对象时的错误报告
返回:立即返回创建的对象或null,这是与上面其他接口不一样的:
2、例子1:
import QtQuick 2.5 Item { id: root width: 1024 height: 600 function createItem() { Qt.createQmlObject("import QtQuick 2.5; Rectangle { x: 100; y: 100; width: 100; height: 100; color: \"blue\" }", root, "dynamicItem"); } Component.onCompleted: root.createItem(); }
四、createComponent
createComponent其实和createObject一样,除了createComponent多了一个指定是否同步创建的参数,可以认为就是一个createObject,这里不加例子了
如图,多了mode参数
长风破浪会有时,直挂云帆济沧海!
可通过下方链接找到博主
https://www.cnblogs.com/judes/p/10875138.html