Reputation: 25
I try to understand how shared qml objects can be used globally by other qml and javascript files. I have a QML app that has two comboboxes in one window. One is parent (country) combo box in ApplicationWindow
, other one is child (city) combo box in Page1.qml
. When selecting a country, the child combo box should have cities of the country at the same time. This is possible when using the comboboxes and the function are in ApplicationWindow
, I had asked a question about it here. With the help of the answer of my previous question I tried to connect child combobox outside of ApplicationWindow
to parent combobox in ApplicationWindow
using qmldir, singleton and javascript.
I tried child combobox's list model to be a singleton object, it doesn't work and it gives error qrc:/script.js:11: Error: Cannot assign QJSValue to QQmlListModel*
main.qml:
import QtQuick 2.11
import QtQuick.Window 2.11
import QtQuick.Controls 2.4
import QtQuick.Layouts 1.3
import Qt.labs.settings 1.0
import "script.js" as JS
ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
property int currentindex: comboBox2.currentIndex
Settings{
property alias country : comboBox2.currentIndex
}
Dialog {
id: dialog
title: "Select Country"
implicitWidth: parent.width
implicitHeight: parent.height/2
Column{
ComboBox {
id: comboBox2
x: 199
y: 176
width: 277
height: 48
currentIndex: 0
model:
ListModel {
ListElement { text: qsTr("USA") }
ListElement { text: qsTr("Russia") }
ListElement { text: qsTr("Iran") }
}
onCurrentIndexChanged:{
currentindex = currentIndex
JS.coord_combo_changed()
}
}
}
}
ColumnLayout{
anchors.horizontalCenter: parent.horizontalCenter
spacing:20
width: parent.width
Button{
anchors.horizontalCenter: parent.horizontalCenter
id:select_country
text:"select country"
onClicked: dialog.open()
}
Page1{
anchors.horizontalCenter: parent.horizontalCenter
}
}
}
Page1.qml:
import QtQuick 2.11
import QtQuick.Controls 2.4
import QtQuick.Layouts 1.3
Page{
RowLayout{
anchors.horizontalCenter: parent.horizontalCenter
spacing:5
width: parent.width
Text{
text:"Select City: "
}
ChildCombo{
id:comboBox1
model: Shared.childmodel
}
}
}
qmldir:
singleton Shared 1.0 Shared.qml
Shared.qml:
pragma Singleton
import QtQuick 2.9
import QtQuick.Controls 2.2
QtObject {
property ListModel childmodel: ChildModel{}
}
ChildModel.qml:
import QtQuick 2.0
ListModel {}
script.js:
function coord_combo_changed(){
if(currentindex === 0){
Shared.childmodel = ["New York", "Washington", "Houston"]
return Shared.childmodel
}
else if (currentindex === 1){
Shared.childmodel = ["Moscow","Saint Petersburg","Novosibirsk"]
return Shared.childmodel
}
else if (currentindex === 2){
Shared.childmodel = ["Tehran","Tabriz","Shiraz"]
return Shared.childmodel
}
}
I also tried to make combobox as a shared object, it also didn't work and it didn't give any error either. Is it possible to update the child combo box?
Thank you.
Upvotes: 1
Views: 641
Reputation: 244301
In QML a model can be a list, a ListModel, a QAbstractItemModel, etc., but those objects are not equivalent. And that is your mistake, you are trying to point out that a ListModel is a list, in this case the solution is to first clean the model and then add the elements with the append method:
function coord_combo_changed(){
var values = [];
if(currentindex === 0){
values = ["New York", "Washington", "Houston"]
}
else if (currentindex === 1){
values = ["Moscow","Saint Petersburg","Novosibirsk"]
}
else if (currentindex === 2){
values = ["Tehran","Tabriz","Shiraz"]
}
Shared.childmodel.clear()
for(var i in values){
Shared.childmodel.append({"text": values[i]});
}
}
On the other hand I see that your code throws warning indicating that you should not use the anchors if the items are within a layout, in your case you should change to:
ColumnLayout{
anchors.horizontalCenter: parent.horizontalCenter
spacing:20
width: parent.width
Button{
Layout.alignment: Qt.AlignHCenter // <---
id:select_country
text:"select country"
onClicked: dialog.open()
}
Page1{
Layout.alignment: Qt.AlignHCenter // <---
}
}
Upvotes: 0