在 SwipeDelegate 上禁用滑动多个项目
Posted
技术标签:
【中文标题】在 SwipeDelegate 上禁用滑动多个项目【英文标题】:Disable swiping multi items on SwipeDelegate 【发布时间】:2017-09-25 06:46:57 【问题描述】:默认情况下,SwipeDelegate 允许滑动多个项目,如下图:
如您所见,多次滑动项目一次打开,我一次只想要一个打开的项目,这意味着如果您打开项目 #1,通过打开项目 #2,项目 #1 应该关闭。我怎样才能做到这一点?
带有 SwipeDelegate 的 ListView 的示例代码:
ListView
id: listView
anchors.fill: parent
delegate: SwipeDelegate
id: delegate
text: modelData
width: parent.width
swipe.right: Rectangle
width: parent.width
height: parent.height
Label
text: qsTr("SOME ACTION BUTTON")
padding: 20
anchors.fill: parent
model: ListModel
id: listModel
ListElement text: "Lorem ipsum dolor sit amet"
ListElement text: "Curabitur sit amet risus"
ListElement text: "Suspendisse vehicula nisi"
ListElement text: "Mauris imperdiet libero"
ListElement text: "Sed vitae dui aliquet augue"
ListElement text: "Praesent in elit eu nulla"
ListElement text: "Etiam vitae magna"
ListElement text: "Pellentesque eget elit euismod"
ListElement text: "Nulla at enim porta"
ListElement text: "Fusce tincidunt odio"
ListElement text: "Ut non ex a ligula molestie"
ListElement text: "Nam vitae justo scelerisque"
ListElement text: "Vestibulum pulvinar tellus"
ListElement text: "Quisque dignissim leo sed gravida"
ScrollIndicator.vertical: ScrollIndicator
【问题讨论】:
请输入代码。 help/MCVE 能否提供minimal reproducible example @derM 我添加一个示例代码,代码是this official example的缩小版 @EligijusPupeikis 我添加一个例子。 【参考方案1】:我会这样做:
import QtQuick 2.9
import QtQuick.Controls 2.3
import QtGraphicalEffects 1.0
ApplicationWindow
id: window
width: 800
height: 600
visible: true
ListView
id: listView
anchors.fill: parent
ButtonGroup
buttons: listView.contentItem.children
delegate: SwipeDelegate
id: delegate
checkable: true
text: modelData
width: parent.width
checked: swipe.complete
onCheckedChanged: if (!checked) swipe.close()
swipe.right: Rectangle
width: parent.width
height: parent.height
color: "#666"
Label
text: qsTr("SOME ACTION BUTTON")
color: "white"
leftPadding: 20
anchors.verticalCenter: parent.verticalCenter
model: ListModel
id: listModel
ListElement text: "Lorem ipsum dolor sit amet"
ListElement text: "Curabitur sit amet risus"
ListElement text: "Suspendisse vehicula nisi"
ListElement text: "Mauris imperdiet libero"
ListElement text: "Sed vitae dui aliquet augue"
ListElement text: "Praesent in elit eu nulla"
ListElement text: "Etiam vitae magna"
ListElement text: "Pellentesque eget elit euismod"
ListElement text: "Nulla at enim porta"
ListElement text: "Fusce tincidunt odio"
ListElement text: "Ut non ex a ligula molestie"
ListElement text: "Nam vitae justo scelerisque"
ListElement text: "Vestibulum pulvinar tellus"
ListElement text: "Quisque dignissim leo sed gravida"
ScrollIndicator.vertical: ScrollIndicator
ButtonGroup
确保一次只能检查一个“按钮”(SwipeDelegate
派生自 AbstractButton
)。 SwipeDelegate
没有视觉效果来表示选中状态,因此我们可以安全地使用它来跟踪应该打开哪个状态。我们仍然需要关闭之前打开的委托,所以这就是
onCheckedChanged: if (!checked) swipe.close()
进来。
【讨论】:
如果您想在拖动另一个时立即关闭当前的,也可以使用checked: swipe.position !== 0
@GrecKo 您的解决方案不起作用,当项目 #1 开始打开时,项目 #2 应该开始关闭,因此两个项目的位置同时发生变化,并导致某种不可预测的行为。跨度>
@Elsiete 很有趣,我做了一个快速测试,它可以正常工作,但它可能不是很健壮。可以改成pressed && swipe.position !== 0 || swipe.complete
,可以去掉位置检查事件。
@GrecKo 是的,现在它就像一个魅力。有趣的是,我尝试了pressed && swipe.position !== 0
并没有弄清楚为什么它不起作用,但是当我看到你的评论时,一切都变得清晰了,谢谢。
@Elsiete:该死的......你不应该这样做,但很高兴知道。您可以关注此报告:bugreports.qt.io/browse/QTBUG-63470【参考方案2】:
受 ButtonGroup 答案的启发,这是我不需要修改代表的解决方案:
SwipeDelegateGroup.qml
import QtQuick 2.9
import QtQuick.Controls 2.2
Item
id: swipeGroup
property ListView listView: parent
QtObject
id: d
property var delegates: swipeGroup.listView.contentItem.children
property var delegateCache: []
onDelegatesChanged:
for (var i = 0; i < d.delegates.length; i++)
var thisItem = d.delegates[i];
if (!thisItem.hasOwnProperty("swipe"))
continue;
if (d.delegateCache.indexOf(thisItem) < 0)
d.delegateCache.push(thisItem);
thisItem.Component.destruction.connect(function()
d.delegateCache.splice(d.delegateCache.indexOf(thisItem), 1)
)
thisItem.swipe.opened.connect(function()
for (var j = 0; j < d.delegates.length; j++)
var otherItem = d.delegates[j];
if (thisItem === otherItem)
continue;
if (!otherItem.hasOwnProperty("swipe"))
continue;
otherItem.swipe.close();
)
然后像这样把它放到 ListView 中:
ListView
SwipeDelegateGroup
delegate: SwipeDelegate
...
【讨论】:
以上是关于在 SwipeDelegate 上禁用滑动多个项目的主要内容,如果未能解决你的问题,请参考以下文章