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

时间:2018-12-30 08:03:32

标签: qt qml singleton

我尝试了解共享qml对象如何被其他qml和javascript文件全局使用。我有一个QML应用程序,在一个窗口中有两个组合框。一个是<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.1.RELEASE</version> <relativePath/> </parent> <groupId>ir.zabetan</groupId> <artifactId>master</artifactId> <version>0.0.1-SNAPSHOT</version> <name>master</name> <packaging>war</packaging> <description>Alireza Zabetan Assignment</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> </dependency> <dependency> <groupId>org.zalando</groupId> <artifactId>problem-spring-web</artifactId> <version>RELEASE</version> </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.9.0</version> </dependency> <dependency> <groupId>com.vladmihalcea</groupId> <artifactId>hibernate-types-52</artifactId> <version>2.2.2</version> </dependency> <!--Swagger--> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>2.8.0</version> <scope>compile</scope> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.8.0</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jersey</artifactId> <version>2.1.1.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-undertow</artifactId> </dependency> <dependency> <groupId>commons-dbcp</groupId> <artifactId>commons-dbcp</artifactId> <version>1.2.2</version> </dependency> </dependencies> <build> <finalName>assignment</finalName> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> <repositories> <repository> <id>spring-snapshots</id> <name>Spring Snapshots</name> <url>https://repo.spring.io/snapshot</url> <snapshots> <enabled>true</enabled> </snapshots> </repository> <repository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/milestone</url> <snapshots> <enabled>false</enabled> </snapshots> </repository> </repositories> <pluginRepositories> <pluginRepository> <id>spring-snapshots</id> <name>Spring Snapshots</name> <url>https://repo.spring.io/snapshot</url> <snapshots> <enabled>true</enabled> </snapshots> </pluginRepository> <pluginRepository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/milestone</url> <snapshots> <enabled>false</enabled> </snapshots> </pluginRepository> </pluginRepositories> <!--<build>--> <!--<pluginManagement>--> <!--<plugins>--> <!--<plugin>--> <!--<groupId>org.apache.maven.plugins</groupId>--> <!--<artifactId>maven-war-plugin</artifactId>--> <!--<version>2.4</version>--> <!--<configuration>--> <!--<warSourceDirectory>src/main/webapp</warSourceDirectory>--> <!--<warName>Assignment</warName>--> <!--<failOnMissingWebXml>false</failOnMissingWebXml>--> <!--</configuration>--> <!--</plugin>--> <!--</plugins>--> <!--</pluginManagement>--> <!--<finalName>Assignment</finalName>--> <!--</build>--> 中的父(国家)组合框,另一个是ApplicationWindow中的子(城市)组合框。选择国家/地区时,子组合框应同时具有该国家/地区的城市。当使用组合框并且函数在Page1.qml中时,这是可能的,我已经问过一个关于here的问题。借助上一个问题的答案,我尝试使用qmldir,singleton和javascript将ApplicationWindow之外的子组合框连接到ApplicationWindow中的父组合框。 我尝试将子组合框的列表模型作为单例对象,但它不起作用并且给出了错误ApplicationWindow

main.qml:

qrc:/script.js:11: Error: Cannot assign QJSValue to QQmlListModel*

Page1.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
    }
    }
}

qmldir:

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

Shared.qml:

singleton Shared 1.0 Shared.qml

ChildModel.qml:

pragma Singleton
import QtQuick 2.9
import QtQuick.Controls 2.2
QtObject {
    property ListModel childmodel: ChildModel{}
}

script.js:

import QtQuick 2.0
ListModel {}

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

谢谢。

1 个答案:

答案 0 :(得分:0)

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