如何在单例中动态更新子 ListModel?

How to dynamically update a child ListModel within a singleton?

我试图了解其他 qml 和 javascript 文件如何全局使用共享的 qml 对象。我有一个 QML 应用程序,其中有两个组合框 window。一个是 ApplicationWindow 中的父(国家)组合框,另一个是 Page1.qml 中的子(城市)组合框。选择国家时,子组合框应同时包含该国家/地区的城市。当使用组合框并且函数在 ApplicationWindow 中时,这是可能的,我已经问过一个关于它的问题 。在我之前问题的答案的帮助下,我尝试使用 qmldir、singleton 和 javascript 将 ApplicationWindow 之外的子组合框连接到 ApplicationWindow 中的父组合框。 我尝试将子组合框的列表模型作为单例对象,但它不起作用并且给出错误 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
}
}

我也试过将组合框作为共享对象,它也没有用,也没有给出任何错误。是否可以更新子组合框?

谢谢。

在 QML 中,模型可以是列表、ListModel、QAbstractItemModel 等,但这些对象并不等同。那是你的错误,你试图指出 ListModel 是一个列表,在这种情况下,解决方案是先清理模型,然后使用 append 方法添加元素:

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]});
    }
}

另一方面,我看到您的代码抛出警告,表明如果项目在布局内,您不应使用锚点,在您的情况下,您应该更改为:

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 // <---
    }
}