我问过类似的问题here 。但该解决方案仅适用于单页 QML 文件。我构建了一个包含许多页面的 QML 应用程序,因此我制作了一个包含添加/删除操作的最喜欢的选项卡。收藏夹标签页中有一个列表模型。在我看来,为了将任何页面添加到收藏夹列表,有必要从示例页面调用收藏夹列表模型,因此当用户单击该操作时,该页面应该作为列表项添加到收藏夹页面。我有两个例子。第一个示例是单页 QML,它添加/删除列表项。但第二个示例不会将示例页面添加/删除到收藏夹列表页面。如何使用 QML 或 JavaScript 访问、保存和恢复列表模型的内容?谢谢。
第一个示例:
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
}
第二个示例:
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{}
}
}
收藏夹.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 示例,我必须使用 Fluid qml 库,因为制作列表菜单很简单。
最佳答案
在您的代码中,您有两个问题:
- 首先是您没有将列表保存在
datastorage
中
[...]
datamodel = JSON.stringify(datamodel)
[...]
必须是:
datastore = JSON.stringify(datamodel)
- 第二个是您在错误的时间保存数据,
onCanGoBackChanged
事件在页面加载后发生。一般来说,做法必须是在item加载完成时加载数据,在item销毁之前保存数据,所以使用Component.onCompleted
比较合适。和Component.onDestruction
事件。
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 文件:
共享.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")
}
]
}
收藏夹.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 中找到。
关于qt - 如何从另一个 QML 访问和控制 ListModel 的内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48891034/