我们在很多的系统中看见可以在屏幕的一个地方长按,然后就可以根据当前显示的上下文弹出一个菜单。菜单中可以有一些选项,比如删除,修改该项。这种一般在ListView或GridView中常见。今天,我们就在这个例程中详细介绍如何实现这个功能。
对ListView来说,我们只需要对它的delegate做一些修改:
Component { id: listDelegate ListItem { id: delegateItem width: listView.width; height: units.gu(10) onPressAndHold: ListView.view.ViewItems.dragMode = !ListView.view.ViewItems.dragMode Image { id: pic height: parent.height - units.gu(1) width: height anchors.verticalCenter: parent.verticalCenter anchors.left: parent.left anchors.leftMargin: units.gu(0.5) source: image } Column { id: content anchors.top: parent.top anchors.left: pic.right anchors.leftMargin: units.gu(2) anchors.topMargin: units.gu(1) width: parent.width - pic.width - units.gu(1) height: parent.height spacing: units.gu(1) Label { text: name } Label { text: description } Label { text: '$' + Number(cost).toFixed(2) font.bold: true } } ListView.onAdd: SequentialAnimation { PropertyAction { target: delegateItem; property: "height"; value: 0 } NumberAnimation { target: delegateItem; property: "height"; to: delegateItem.height; duration: 250; easing.type: Easing.InOutQuad } } ListView.onRemove: SequentialAnimation { PropertyAction { target: delegateItem; property: "ListView.delayRemove"; value: true } NumberAnimation { target: delegateItem; property: "height"; to: 0; duration: 250; easing.type: Easing.InOutQuad } // Make sure delayRemove is set back to false so that the item can be destroyed PropertyAction { target: delegateItem; property: "ListView.delayRemove"; value: false } } /* create an empty item centered in the image to align the popover to */ Item { id: emptyItemForCaller anchors.centerIn: parent z: 100 } Component { id: actPopComp ActionSelectionPopover { id: actPop delegate: ListItems.Standard { text: action.text } actions: ActionList { Action { text: "Add 1 dollar" iconName: "add" onTriggered: { PopupUtils.close(actPop); console.log("Add 1 dollar"); fruitModel.setProperty(index, "cost", cost + 1.0); } } Action { text: "Deduct 1 dollar" iconName: "remove" onTriggered: { PopupUtils.close(actPop); console.log("Deduct 1 dollar"); fruitModel.setProperty(index, "cost", Math.max(0,cost-1.0)); } } Action { text: "delete" iconName: "delete" onTriggered: { console.log("delete the item!"); fruitModel.remove(index) } } } } } MouseArea { anchors.fill: parent onPressAndHold: { PopupUtils.open(actPopComp, emptyItemForCaller); } onClicked: { console.log("we can do something else!"); } } } }
从上面的代码中可以看出:
/* create an empty item centered in the image to align the popover to */ Item { id: emptyItemForCaller anchors.centerIn: parent z: 100 }
我们使用了一个空的Item来作为一个placeholder。这个是为了给我们在长按ListView中项时,来提供一个位置显示我们的Popup menu。
当我们长按我们的ListView中的项时,我们可以通过如下的方法来得到事件并弹出我们所需要的Popup:
MouseArea { anchors.fill: parent onPressAndHold: { PopupUtils.open(actPopComp, emptyItemForCaller); } onClicked: { console.log("we can do something else!"); } }
这里,我们的actPopComp的设计为:
Component { id: actPopComp ActionSelectionPopover { id: actPop delegate: ListItems.Standard { text: action.text } actions: ActionList { Action { text: "Add 1 dollar" iconName: "add" onTriggered: { PopupUtils.close(actPop); console.log("Add 1 dollar"); fruitModel.setProperty(index, "cost", cost + 1.0); } } Action { text: "Deduct 1 dollar" iconName: "remove" onTriggered: { PopupUtils.close(actPop); console.log("Deduct 1 dollar"); fruitModel.setProperty(index, "cost", Math.max(0,cost-1.0)); } } Action { text: "delete" iconName: "delete" onTriggered: { console.log("delete the item!"); fruitModel.remove(index) } } } } }
在这里,我们有三个Action的菜单。
运行我们的应用:
整个项目的源码在: git clone https://gitcafe.com/ubuntu/contextmenu.git
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-11-07 00:32:12