Как динамически обновить дочернюю ListModel в пределах синглтона? - PullRequest
0 голосов
/ 30 декабря 2018

Я пытаюсь понять, как общие объекты qml могут использоваться глобально другими файлами qml и javascript.У меня есть приложение QML, которое имеет два комбинированных списка в одном окне.Один из них - это поле со списком родителей (стран) в ApplicationWindow, другое - поле со списком детей (городов) в Page1.qml.При выборе страны в дочернем поле со списком одновременно должны быть указаны города страны.Это возможно при использовании комбинированных списков и функции в ApplicationWindow, я задавал вопрос об этом здесь .С помощью ответа на мой предыдущий вопрос я попытался соединить дочерний выпадающий список вне ApplicationWindow с родительским выпадающим списком в ApplicationWindow, используя qmldir, singleton и javascript.Я пытался использовать модель списка дочерних списков в качестве одноэлементного объекта, он не работает и выдает ошибку 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
}
}

Я также пытался сделать выпадающий список общим объектом, он также не работал и не выдавал никаких ошибок.Можно ли обновить дочернее поле со списком?

Спасибо.

1 Ответ

0 голосов
/ 30 декабря 2018

В QML модель может быть списком, ListModel, QAbstractItemModel и т. Д., Но эти объекты не эквивалентны.И это ваша ошибка, вы пытаетесь указать, что ListModel является списком, в этом случае решение состоит в том, чтобы сначала очистить модель, а затем добавить элементы с помощью метода добавления:

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 // <---
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...