如何从另一个QML

时间:2018-02-20 17:29:57

标签: qt qml settings

我曾问过类似的问题here。但此解决方案仅适用于单页QML文件。我构建了一个包含许多页面的QML应用程序,因此我制作了一个包含“添加/删除”操作的收藏夹选项卡。收藏夹标签页中有一个列表模型。在我看来,为了将任何页面添加到收藏夹列表,有必要从示例页面调用收藏列表模型,因此当用户单击该操作时,该页面应作为列表项添加到收藏夹页面。我有两个例子。第一个例子是单页QML,它添加/删除列表项。但第二个示例不会将示例页面添加/删除到收藏列表页面。如何使用QML或Java Script访问,保存和恢复列表模型的内容?感谢。

第一个例子:

enter image description here

main.qml

import QtQuick 2.6
import QtQuick.Controls 2.3
import QtQuick.Controls.Material 2.0
import Qt.labs.settings 1.0
ApplicationWindow{
    id:main
    width: 640
    height: 480
    visible:true
    title: "Menu"
    property string datastore: ""
    property int countt2: 0
    Settings{
        property alias datastore: main.datastore
        property alias mycount: main.countt2
    }
    menuBar:MenuBar {
        Menu{
        title: main.title
            Action {
                id:action2
                text: qsTr("On/Off")
                onTriggered:{
                    countt2++
                    console.log("triggered works.Count/2: "+ countt2%2)
                    if(countt2%2==1){
                        console.log("it must be added")
                        dataModel.append({ "title": "Application Tools" })
                    }
                    else if(countt2%2==0){
                        console.log("list must be removed. count/2: "+countt2%2)
                        return dataModel.remove(dataModel.index)
                    }
                }
            }
        }
    }
    Component.onCompleted: {
        if(datastore){
            dataModel.clear()
            var datamodel=JSON.parse(datastore)
            for (var i=0; i<datamodel.length; ++i) dataModel.append(datamodel[i])
        }
        console.log("onCompleted works right now.")
    }
    onClosing: {
        var datamodel = []
        for (var i=0;i<dataModel.count; ++i) datamodel.push(dataModel.get(i))
        datastore=JSON.stringify(datamodel)
        console.log("datastore: "+datastore)
    }
        ListView {
            id:malist
            width: parent.width
            height: parent.height
            focus: true
            interactive: true
            clip: true
            model:FavModel{
            id:dataModel
            }
            delegate: ItemDelegate {
                width: parent.width
                text: model.title
            }
        }
}

FavModel.qml:

import QtQuick 2.0
ListModel {
    id:dataModel
    }

第二个例子:

enter image description here

enter image description here

main.qml:

import QtQuick 2.6
import QtQuick.Controls 2.2
import QtQuick.Controls.Material 2.0
import QtQuick.Layouts 1.3
import Fluid.Controls 1.0
import QtQuick.Window 2.3
ApplicationWindow{
    id:main
    width: 640
    height: 480
    visible:true
    title: "Example App"
    initialPage:TabbedPage {
        title: main.title
        Tab{
            title:"APPS"
        ListView {
            id:malist
            width: parent.width
            height: parent.height
            focus: true
            interactive: true
            clip: true
            model:ListModel {
            id:appModel
            ListElement { title: qsTr("Page1"); source: "qrc:/SampePage.qml" }
            }
            delegate: ListItem {
                text: model.title
                onClicked: pageStack.push(model.source)
            }
        }
        }
        Favourites{}
    }
}

Favourites.qml:

import QtQuick 2.6
import QtQuick.Controls 2.0
import QtQuick.Controls.Material 2.0
import Fluid.Controls 1.0
Tab{
    title:"FAVORITES"
ListView {
    id:favorites
    width: parent.width
    height: parent.height
    focus: true
    interactive: true
    clip: true
    model:FavModel {
    id:favModel
    }
    delegate: ListItem {
        text: model.title
        onClicked: pageStack.push(model.source)
    }
}
}

FavModel.qml:

import QtQuick 2.0

ListModel {
    id:dataModel
    }

SamplePage.qml:

import QtQuick 2.9
import QtQuick.Controls 2.2
import QtQuick.Controls.Material 2.2
import Fluid.Controls 1.0
import Qt.labs.settings 1.0
Page{
    title:qsTr("Page1")
    appBar.maxActionCount: 2
    id:sampleapp
    property string datastore: ""
    property int countt2: 0
    Settings{
        id:mysetting4
        property alias datastore: sampleapp.datastore
        property alias mycount: sampleapp.countt2
    }
    FavModel{
        id:dataModel
    }
    Component.onCompleted: {
        console.log("onCompleted works right now.")
        if(datastore){
            dataModel.clear()
            var datamodel = JSON.parse(datastore)
            for (var i=0; i<datamodel.length; ++i) dataModel.append(datamodel[i])
        }
    }
    onCanGoBackChanged: {
        var datamodel=[]
        for (var i=0; i<dataModel.count; ++i) datamodel.push(dataModel.get(i))
        datamodel = JSON.stringify(datamodel)
        console.log("datastore: "+datastore)
    }
    actions: [
        Action {
          id:favourite2
            onTriggered:{
                countt2++
                console.log("Count/2: "+ countt2%2)
                if(countt2%2==1){
                    console.log("List must be added")
                    dataModel.append({ "title": "Application Tools", "source": "qrc:/SampePage.qml" })
                }
                else if(countt2%2==0){
                    console.log("List must be removed.")
                    return dataModel.remove(dataModel.index)
                }
            }
            icon.name: "toggle/star"
            toolTip: qsTr("Add/Remove")
        }
    ]
}

*我无法在第二个例子中制作Qt Quick Controls 2.0示例,我不得不使用流畅的qml库,因为制作列表菜单很简单。

1 个答案:

答案 0 :(得分:2)

在您的代码中,您有两个问题:

  • 首先,您不是在datastorage
  • 中保存列表
[...]
datamodel = JSON.stringify(datamodel)
[...]

必须:

datastore = JSON.stringify(datamodel)
  • 第二个是您在错误的时间保存数据,在加载页面后发生onCanGoBackChanged事件。通常,方法必须是在项目加载完成后加载数据,并在项目销毁之前保存数据,因此使用Component.onCompletedComponent.onDestruction事件是合适的。 / LI>
Component.onCompleted: {
    console.log("onCompleted works right now.")
    if(datastore){
        dataModel.clear()
        var datamodel = JSON.parse(datastore)
        for (var i=0; i<datamodel.length; ++i) dataModel.append(datamodel[i])
    }
}
Component.onDestruction: {
    console.log("onDestruction works right now.")
    var datamodel=[]
    for (var i=0; i<dataModel.count; ++i) datamodel.push(dataModel.get(i))
    datastore = JSON.stringify(datamodel)
    console.log("datastore: "+datastore)
}

另一个小错误,因为我认为这是一个测试代码。假设dataModel中没有数据且countt2是偶数,那么您将要删除dataModel中不存在的数据。

<强>更新

Settings用于存储数据,并且能够在关闭应用程序后恢复,但如果要在多个文件之间共享数据,可能的解决方案是实现singleton,因为这是整个应用程序中存在的单个元素。在任何地方都可以轻松修改它。

要构建单例,我们使用以下结构创建.qml文件:

<强> Shared.qml

pragma Singleton
import QtQuick 2.0

QtObject {
    property var favModel: FavModel{}
}

然后我们添加另一个名为qmldir的文件:

<强> qmldir

singleton Shared 1.0 Shared.qml

然后我导入它,我们以下列方式使用它:

import "."

[...]

Shared.favModel.some_function()

例如在您的具体案例中:

<强> main.qml

import QtQuick 2.6
import QtQuick.Controls 2.2
import QtQuick.Controls.Material 2.0
import QtQuick.Layouts 1.3
import Fluid.Controls 1.0
import QtQuick.Window 2.3
import Qt.labs.settings 1.0
import "."

ApplicationWindow{
    id:main
    width: 640
    height: 480
    visible:true
    title: "Example App"

    property string datastore: ""
    Settings{
        property alias datastore: main.datastore
    }

    Component.onCompleted: {
        console.log("onCompleted works right now.")
        if(datastore){
            Shared.favModel.clear()
            var datamodel = JSON.parse(datastore)
            for (var i=0; i<datamodel.length; ++i) Shared.favModel.append(datamodel[i])
        }
    }

    Component.onDestruction: {
        console.log("onDestruction works right now.")
        var datamodel=[]
        for (var i=0; i<Shared.favModel.count; ++i) datamodel.push(Shared.favModel.get(i))
        datastore = JSON.stringify(datamodel)
        console.log("datastore: "+datastore)
    }
    [...]
}

<强> SamplePage.qml

import QtQuick 2.9
import QtQuick.Controls 2.2
import QtQuick.Controls.Material 2.2
import Fluid.Controls 1.0
import "."

Page{
    title:qsTr("Page1")
    appBar.maxActionCount: 2
    id:sampleapp

    actions: [
        Action {
            id:favourite2
            onTriggered:{
                Shared.favModel.append({ "title": "Application Tools", "source": "qrc:/SamplePage.qml" })
            }
            icon.name: "toggle/star"
            toolTip: qsTr("Add/Remove")
        }
    ]
}

<强> Favourites.qml

import QtQuick 2.6
import QtQuick.Controls 2.0
import QtQuick.Controls.Material 2.0
import Fluid.Controls 1.0

import "."

Tab{
    title:"FAVORITES"
    id:favtab

    ListView {
        id:favorites
        width: parent.width
        height: parent.height
        focus: true
        interactive: true
        clip: true
        model: Shared.favModel
        delegate: ListItem {
            text: model.title
            onClicked: pageStack.push(model.source)
        }
    }
}

完整且更新的示例可在以下link

中找到