Qt QML ListView-更改除当前项以外的所有项
我在使用Qt5.7和Qt QML ListView-更改除当前项以外的所有项,qt,listview,model,qml,qtquick2,Qt,Listview,Model,Qml,Qtquick2,我在使用Qt5.7和QtQuick 2.0时,正在学习Qt4.8的教程(每个条目中没有flickable内容)。列表视图的工作方式如下所示: 用户单击列表中的项目 显示项目的备选(详细)视图 用户必须单击详细视图中的Close按钮,将条目状态重置为默认的紧凑视图 这会导致混乱,如果用户单击所有项目,在某种情况下,所有项目都将显示在其完整视图中。让用户在每次打开详细视图时单击Close按钮也不是那么方便 我已将条目更改为在用户单击视图时关闭。我还试图防止这种混乱,并实现更流畅的行为: 用户单击列表
QtQuick 2.0
时,正在学习Qt4.8的教程(每个条目中没有flickable内容)。列表视图的工作方式如下所示:
用户单击列表中的项目
显示项目的备选(详细)视图
用户必须单击详细视图中的Close
按钮,将条目状态重置为默认的紧凑视图
这会导致混乱,如果用户单击所有项目,在某种情况下,所有项目都将显示在其完整视图中。让用户在每次打开详细视图时单击Close
按钮也不是那么方便
我已将条目更改为在用户单击视图时关闭。我还试图防止这种混乱,并实现更流畅的行为:
用户单击列表中的项目
将显示项目的备选视图
用户单击详细视图,将条目状态重置为默认的紧凑视图或
用户单击另一个条目,当前详细视图中的所有条目都将重置为其压缩视图
目前,我正在遍历我的列表视图的contentItem.children[loop\u index]
,并将状态设置为”
(“详细信息”
=显示详细视图
”=显示压缩视图)。由于ListView
的工作方式(按需加载/卸载代理),这是非常不可靠的,当我尝试访问其他代理的状态时,我经常会得到一个未定义的引用。下面的MouseArea
,我用它来做所有这些,是每个代表的一部分:
// state is a QML `State` that is bound to the delegate (see below for the details on it)
MouseArea {
anchors.fill: background
onClicked: {
// Iterate through all other entries and close them
for (var entry = 0; entry < listView.count; ++entry) {
if(listView.contentItem.children[entry] !== gestureEntry) {
console.log("Hide other element");
listView.contentItem.children[entry].state = ""; // IT FAILS HERE (SOMETIMES)
}
}
// Change view of current entry
if(gestureEntry.state === "Details") {
gestureEntry.state = "";
console.log("Hiding details")
}
else {
gestureEntry.state = "Details";
console.log("Showing details");
}
}
}
我认为状态
信息可以存储在列表模型
本身中,从而可以迭代模型的内容(与代理的内容不同,这些内容总是存在),但是我不知道如何自动更新我的列表(以及当前可见/不可见的代理)当模型中的条目发生更改时。从我目前发现的情况来看,这似乎是不可能的,因为ListView
没有主动监视它的ListModel
真的是这样吗?如果是,那么是否可以用不同的方法解决此问题?为什么不使用列表视图的currentIndex
属性?
只需按如下方式修改您的委托:
Item {
id: gestureEntry
...
state: ListView.isCurrentItem?"Details":""
...
MouseArea {
anchors.fill: background
onClicked: {
if(listView.currentIndex == index)
listView.currentIndex = -1
else
listView.currentIndex = index
}
}
}
编辑:
上述解决方案的唯一问题是,加载时,ListView
中的一个条目被预选,这会自动触发该条目的详细视图。为了避免出现这种情况,需要将以下内容添加到列表视图中:
Component.onCompleted: {
listView.currentIndex = -1;
}
这确保不会预选任何条目。我想这是一个问题,因为您在代理中存储了状态。您不应该像委托
-property()中所述那样执行此操作,因为委托离开视图时会被重用
当:ListView.isCurrentItem
处于状态并依赖于ListView的值时,至少应该使用。因此,只有您当前的代理被最大化。然后在MouseArea中只设置'ListView.view.currentIndex=index'不要在功能中手动更改状态
我也遇到了同样的问题,完全删除了状态,只使用了附加的属性ListView.iscurrentem
。但是将状态绑定到ListView中的值也应该起作用,因为它不存储在委托中
最简单的例子:
import QtQuick 2.0
Item {
width: 800
height: 600
ListView {
id: view
anchors.fill: parent
model: 3
spacing: 5
currentIndex: -1
delegate: Rectangle {
id: delegate
color: ListView.isCurrentItem ? "lightblue" : "green" // directly change properties depending on isCurrentItem
height: 100
width: 100
states: State {
name: "maximized"
when: delegate.ListView.isCurrentItem // bind to isCurrentItem to set the state
PropertyChanges {
target: delegate
height: 200
}
}
MouseArea {
anchors.fill: parent
//onClicked: delegate.ListView.view.currentIndex = model.index // if only selection is wanted
onClicked: {
//console.debug("click");
if (delegate.ListView.isCurrentItem)
{
delegate.ListView.view.currentIndex = -1;
}
else
{
delegate.ListView.view.currentIndex = model.index;
}
}
}
Text {
anchors.centerIn: parent
text: index
}
}
Text {
text: "CurrentIndex: " + parent.currentIndex
}
}
}
我在ListView.view.currentIndex=index处得到一个TypeError
代码>我还尝试将其更改为listView.view.currentIndex=index代码>(因为我的ListView
具有该ID,但问题仍然存在。ListView会像索引一样附加到您的代理根项。也许您必须显式使用delegateId.ListView.currentIndex=delegateId.index
。甚至在代理中调用一个信号,它应该可以工作。我已经使用了很多次,而且确实可以工作这里,使用Qt 5.5.1.gestureEntry
是gestureDelegate
中的项,它是我的ListView
的委托中使用的组件e> 第一次出现的问题是,用户在单击所选条目时无法更改回压缩视图。啊,等等。现在,单击条目后关闭不起作用…XD我实际上需要if-else
内部onClicked
。这打破了您的解决方案。:-/编辑了我的答案。希望这将我这次工作:)剩下的唯一问题是第一次加载ListView
时,第一个条目(我猜加载列表时预选的条目)在详细视图中。修复了它。添加了Component.onCompleted:{ListView.currentIndex=-1;}
,以避免预选条目。
import QtQuick 2.0
Item {
width: 800
height: 600
ListView {
id: view
anchors.fill: parent
model: 3
spacing: 5
currentIndex: -1
delegate: Rectangle {
id: delegate
color: ListView.isCurrentItem ? "lightblue" : "green" // directly change properties depending on isCurrentItem
height: 100
width: 100
states: State {
name: "maximized"
when: delegate.ListView.isCurrentItem // bind to isCurrentItem to set the state
PropertyChanges {
target: delegate
height: 200
}
}
MouseArea {
anchors.fill: parent
//onClicked: delegate.ListView.view.currentIndex = model.index // if only selection is wanted
onClicked: {
//console.debug("click");
if (delegate.ListView.isCurrentItem)
{
delegate.ListView.view.currentIndex = -1;
}
else
{
delegate.ListView.view.currentIndex = model.index;
}
}
}
Text {
anchors.centerIn: parent
text: index
}
}
Text {
text: "CurrentIndex: " + parent.currentIndex
}
}
}