一、動態加載和實例化對象: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參數