QML:更新嵌套的 ListView
QML: Update a nested ListView
我正在制作一个关于 Sailfish 的电视指南 OS,并且遇到了一个 - 目前 - 障碍。
因为我想有可能为自定义列表标记每个条目
我需要修改后面的模型。我试过直接修改模型:
model.favorite = true
但这不起作用。我试图修改底层
arrayOfObjects
,但这并未反映在 UI 中,而且我无法触发更新,因为我无法访问 ListView。我试过做一个定制的模型,但是因为我不能引用它的实例,所以没有用。
下面是一个非常简化的布局表示,主要使用基本的 QML。
Page {
Flickable {
Column {
SlideshowView { // PathView
model: arrayOfObjects
delegate: channelDelegate
}
}
}
Component {
id: channelDelegate
ListView {
id: channelList
// ProgramModel just iterates thru arrayOfObjects and appends them
model: ProgramModel {
programs: arrayOfObjects
}
delegate: programDelegate
Component.onCompleted: {
// I can't reference channelList from here.
}
}
}
Component {
id: programDelegate
ListItem {
Button {
onClicked: {
// How do I reference channelList?
// Doing it by name doesn't work.
}
}
}
}
}
我试过调用 ApplicationWindow(有效)来发送一个我连接到的信号
在 channelList.onCompleted 中(也有效),但由于我无法从中引用列表
那里没有帮助。
我使用的是 QT 5.6,所以某些解决方案可能不起作用。
而且我真的更愿意保持它是纯 QML;没有 C++。
我无法准确重现你的案例,但也许这个简单的例子能以某种方式帮助你。
import QtQuick 2.6
import QtQuick.Window 2.2
import QtQuick.Controls 2.2
Window {
id: mainWrapper
visible: true
width: 640
height: 480
title: qsTr("Hello World")
signal updateModel(int id, string name)
Component {
id: listWrapper
ListView {
id: list
model: [
{ name: "name0" },
{ name: "name1" },
{ name: "name2" }
]
delegate: Loader {
width: parent.width
property variant model: modelData
property int modelIndex: index
sourceComponent: listDelegate
}
function updateModelName(id, name) {
var listModel = list.model
listModel[id].name = name
list.model = listModel
}
}
}
Loader {
id: loadedList
x: 0
anchors.fill: parent
sourceComponent: listWrapper
Component.onCompleted: {
mainWrapper.updateModel.connect(loadedList.item.updateModelName)
}
}
Component {
id: listDelegate
Rectangle {
id: listRow
width: 200
height: 80
Text {
text: model.name
}
Button {
x: 100
text: "update"
onClicked: {
mainWrapper.updateModel(modelIndex, "better_name"+modelIndex)
}
}
}
}
}
这个例子的线索是使用信号和函数来更新模型。
由于SlideshowView 取代了DaszuOne 的答案中的焦点,即切换幻灯片,list.model = listModel
导致整个视图发生变化。更改模型中的单个条目不会触发更新,因此需要更多代码才能实现。因此,在反复考虑之后,我决定这样做 "the right way" 会比简单的方法更麻烦和难以阅读。
我做了一个很简单的wrapper,你用什么样的持久化存储就可以用,只有两个方法:setFavorite()
和isFavorite
。
在委托中,我更新了 onCompleted 中的 属性,因此每次需要渲染元素时都会调用它:
Component.onCompleted: {
favorite = favorites.isFavorite(model.channelId, model.id)
}
我的结论是,DaszuOne 的答案是正确的 - 但在这种情况下不是;)
感谢大家的帮助,让我更好地理解了QML。
我正在制作一个关于 Sailfish 的电视指南 OS,并且遇到了一个 - 目前 - 障碍。
因为我想有可能为自定义列表标记每个条目
我需要修改后面的模型。我试过直接修改模型:
model.favorite = true
但这不起作用。我试图修改底层
arrayOfObjects
,但这并未反映在 UI 中,而且我无法触发更新,因为我无法访问 ListView。我试过做一个定制的模型,但是因为我不能引用它的实例,所以没有用。
下面是一个非常简化的布局表示,主要使用基本的 QML。
Page {
Flickable {
Column {
SlideshowView { // PathView
model: arrayOfObjects
delegate: channelDelegate
}
}
}
Component {
id: channelDelegate
ListView {
id: channelList
// ProgramModel just iterates thru arrayOfObjects and appends them
model: ProgramModel {
programs: arrayOfObjects
}
delegate: programDelegate
Component.onCompleted: {
// I can't reference channelList from here.
}
}
}
Component {
id: programDelegate
ListItem {
Button {
onClicked: {
// How do I reference channelList?
// Doing it by name doesn't work.
}
}
}
}
}
我试过调用 ApplicationWindow(有效)来发送一个我连接到的信号 在 channelList.onCompleted 中(也有效),但由于我无法从中引用列表 那里没有帮助。
我使用的是 QT 5.6,所以某些解决方案可能不起作用。 而且我真的更愿意保持它是纯 QML;没有 C++。
我无法准确重现你的案例,但也许这个简单的例子能以某种方式帮助你。
import QtQuick 2.6
import QtQuick.Window 2.2
import QtQuick.Controls 2.2
Window {
id: mainWrapper
visible: true
width: 640
height: 480
title: qsTr("Hello World")
signal updateModel(int id, string name)
Component {
id: listWrapper
ListView {
id: list
model: [
{ name: "name0" },
{ name: "name1" },
{ name: "name2" }
]
delegate: Loader {
width: parent.width
property variant model: modelData
property int modelIndex: index
sourceComponent: listDelegate
}
function updateModelName(id, name) {
var listModel = list.model
listModel[id].name = name
list.model = listModel
}
}
}
Loader {
id: loadedList
x: 0
anchors.fill: parent
sourceComponent: listWrapper
Component.onCompleted: {
mainWrapper.updateModel.connect(loadedList.item.updateModelName)
}
}
Component {
id: listDelegate
Rectangle {
id: listRow
width: 200
height: 80
Text {
text: model.name
}
Button {
x: 100
text: "update"
onClicked: {
mainWrapper.updateModel(modelIndex, "better_name"+modelIndex)
}
}
}
}
}
这个例子的线索是使用信号和函数来更新模型。
由于SlideshowView 取代了DaszuOne 的答案中的焦点,即切换幻灯片,list.model = listModel
导致整个视图发生变化。更改模型中的单个条目不会触发更新,因此需要更多代码才能实现。因此,在反复考虑之后,我决定这样做 "the right way" 会比简单的方法更麻烦和难以阅读。
我做了一个很简单的wrapper,你用什么样的持久化存储就可以用,只有两个方法:setFavorite()
和isFavorite
。
在委托中,我更新了 onCompleted 中的 属性,因此每次需要渲染元素时都会调用它:
Component.onCompleted: {
favorite = favorites.isFavorite(model.channelId, model.id)
}
我的结论是,DaszuOne 的答案是正确的 - 但在这种情况下不是;)
感谢大家的帮助,让我更好地理解了QML。