Dynamic QML for each item of list view
-
Hi all,
I want to create UI to manage and control devices.
On the left side is the list of device. On the right side is the UI to display device properties.
When I select device from list view on left side, I will load qml dynamically to display UI for each kind of device.
Because each device has different properties. The UI will look as below.Below is code to dynamic load qml file for each device when device is selected from list (in onClicked()).
Function createDeviceDetailUI() will call Qt.createComponent(), component.createObject() to load qml file.ListView { Layout.fillHeight: true Layout.fillWidth: true spacing: 5 model: dashboard.devices clip: true delegate: Rectangle { width: ListView.view.width height: 35 color: "#F5FAFE" MouseArea { anchors.fill: parent hoverEnabled: true onEntered: parent.color = "#CFE8FC" onExited: parent.color = "#F5FAFE" Label { text: modelData.deviceName } onClicked: { if (modelData.deviceType === "QT Fan") { createDeviceDetailUI("QtFanDevice.qml") } } } } }
I have difficulty to display device property in loaded qml file, because I can't access modelData to get device property such as modelData.fanSpeed in loaded qml like in listview (with modelData.deviceName, modelData.deviceType). Do you have suggestion to solve this issue?
And another question, to create UI as above image, Is there any other way without loading qml dynamically?
-
I'm not really certain to understand all of your request, but as far as I understand DelegateChooser might be part of the solution.
-
Why do you want to access like this ?
- From ListView delegate emit the signal along with index.
- Keep the right side pane separate from listView
- onSignalFromList view load the new page on right side & pass the index.
- Using the index get the what ever the data from model with Q_INVOKABLE method getData(index)
-
Hi @dheerendra
I followed steps as your recommendation.
I have another issue. Right side pane still catch the signal from list view although I destroyed it when create new pane for other device. The implemented code as below.Function to load right side pane
property var deviceDetailUI: null function createDeviceDetailUI(deviceQmlFile, listIndex,) { if (deviceDetailUI !== null) { console.log("+++Destroying object") deviceDetailUI.destroy() deviceDetailUI = null } console.log("***Creating new object") var deviceDetailComponent = Qt.createComponent(deviceQmlFile) deviceDetailUI = deviceDetailComponent.createObject(deviceDetail); deviceDetailUI.listIndex = listIndex }
Load right side pane, when list item is selected
onClicked: { deviceList.currentIndex = index if (modelData.deviceType === "QT Fan") { createDeviceDetailUI("QtFanDevice.qml", index) } }
When right side pane is loaded, connect to function qtFanPropsUpdate() to handle signal from list view
Component.onCompleted: { deviceList.forwardDevicePropertyChanged.connect(qtFanPropsUpdate) }
When I click on the list item multiple times, I saw log message to destroy and create object.
qml: +++Destroying object qml: ***Creating new object
I expect function handles signal from list view called once when I click on list item. But when I click on list item 2nd time, handler function called 2 times. when I click on list item 3rd time, handler function called 3 times. It seems that deviceDetailUI.destroy() doesn't destroy loaded qml object immediately.
I try to disconnect the signal from loaded object as below. Handler function works properly when I click on list item multiple times.
Component.onDestruction: { deviceList.forwardDevicePropertyChanged.disconnect(qtFanPropsUpdate) }
My question is when loaded ui object is destroyed? Is it proper way to destroy loaded object with deviceDetailUI.destroy() function?
-
Your connect is executed multiple time. Hence it is executed multiple time. If you do 10 time, it will execute 10 times as well :).
I'm not sure what is the semantics of the connect here ?
What is deviceList ? Where is the method qFanPropsUpdate(). Since you are disconnecting it perfectly ok.
Component.onCompleted: {
deviceList.forwardDevicePropertyChanged.connect(qtFanPropsUpdate)
}