Issue
I want to use comboBox which it’s model is taken from a nested model.
The simplified Code:
main.qml:
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.15
ApplicationWindow {
id: applicationWindow
width: 300
height: 200
visible: true
title: qsTr("01_Change_Model_Data")
ListModel {
id: listModel1
ListElement {
labelText: "ComboBox 1:"
//subItems: ["First", "Second", "Third"]
subItems: [
ListElement {text: "First"},
ListElement {text: "Second"},
ListElement {text: "Third"}
]
}
ListElement {
labelText: "ComboBox 2:"
//subItems: ["First", "Second", "Third"]
subItems: [
ListElement {text: "First"},
ListElement {text: "Second"},
ListElement {text: "Third"}
]
}
}
Button {
id: loadUnloadBtn
height: 24
width: 50
text: "Load"
anchors {
right: parent.right
rightMargin: 20
top: parent.top
topMargin: 10
}
onClicked: {
if(comboBoxAreaLoader.source == "") {
comboBoxAreaLoader.source = "ComboBoxArea.qml"
}else {
comboBoxAreaLoader.source = ""
}
}
}
Loader {
id: comboBoxAreaLoader
anchors {
top: parent.top
topMargin: 10
bottom: parent.bottom
bottomMargin: 10
left: parent.left
leftMargin: 10
right: parent.right
rightMargin: 80
}
source: ""
property variant comboBoxModel: subItems
onStatusChanged: if(status == Loader.Ready) comboBoxModelAlias = comboBoxModel
}
}
ComboBoxArea.qml:
import QtQuick 2.15
import QtQuick.Controls 2.15
Item {
id: listViewDelegate
ListView {
id: listView1
anchors.fill: parent
model: listModel1
delegate: listElementDelegate
spacing: 6
}
Component {
id: listElementDelegate
Rectangle {
id: delegateRectangleRoot
property alias comboBoxModelAlias: comboBox.model
height: 30
width: 200
Label {
id: comboBoxNameLabel
color: "red"
width: 80
height: 30
anchors {
left: parent.left
leftMargin: 10
}
text: labelText
verticalAlignment: Text.AlignVCenter
}
ComboBox {
id: comboBox
height: 30
width: 100
//model: ["First", "Second", "Third"]
anchors {
left: comboBoxNameLabel.right
leftMargin: 10
verticalCenter: comboBoxNameLabel.verticalCenter
}
}
}
}
}
I think main problem is defining subItems in nested list. First, I tried to declare it as js list like:
subItems: ["First", "Second", "Third"]
But I got an error:
ListElement: cannot use script for property value
Then I tried to change it with listElements:
subitems: [
ListElement {text: "First"},
ListElement {text: "Second"},
ListElement {text: "Third"}
]
This time I got two errors:
ReferenceError: subItems is not defined
Error: Invalid write to global property "comboBoxModelAlias"
Actually I’m confused. Do you have any idea what I am doing wrong?
Solution
I think you were just making it a little more complex than it needed to be. By declaring subItems like below, they automatically become ListModels. And you can just refer to them in the delegate like you do labelText
.
main.qml:
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.15
ApplicationWindow {
id: applicationWindow
width: 300
height: 200
visible: true
title: qsTr("01_Change_Model_Data")
ListModel {
id: listModel1
ListElement {
labelText: "ComboBox 1:"
subItems: [
ListElement {text: "First"},
ListElement {text: "Second"},
ListElement {text: "Third"}
]
}
ListElement {
labelText: "ComboBox 2:"
subItems: [
ListElement {text: "First"},
ListElement {text: "Second"},
ListElement {text: "Third"}
]
}
}
Button {
id: loadUnloadBtn
height: 24
width: 50
text: "Load"
anchors {
right: parent.right
rightMargin: 20
top: parent.top
topMargin: 10
}
onClicked: {
if(comboBoxAreaLoader.source == "") {
comboBoxAreaLoader.source = "ComboBoxArea.qml"
}else {
comboBoxAreaLoader.source = ""
}
}
}
Loader {
id: comboBoxAreaLoader
anchors {
top: parent.top
topMargin: 10
bottom: parent.bottom
bottomMargin: 10
left: parent.left
leftMargin: 10
right: parent.right
rightMargin: 80
}
}
}
ComboBoxArea.qml:
import QtQuick 2.15
import QtQuick.Controls 2.15
Item {
id: listViewDelegate
ListView {
id: listView1
anchors.fill: parent
model: listModel1
delegate: listElementDelegate
spacing: 6
}
Component {
id: listElementDelegate
Rectangle {
id: delegateRectangleRoot
height: 30
width: 200
Label {
id: comboBoxNameLabel
color: "red"
width: 80
height: 30
anchors {
left: parent.left
leftMargin: 10
}
text: labelText
verticalAlignment: Text.AlignVCenter
}
ComboBox {
id: comboBox
height: 30
width: 100
model: subItems
anchors {
left: comboBoxNameLabel.right
leftMargin: 10
verticalCenter: comboBoxNameLabel.verticalCenter
}
}
}
}
}
Answered By – David K. Hess
Answer Checked By – Marilyn (BugsFixing Volunteer)