我们在非常多的系统中看见能够在屏幕的一个地方长按,然后就能够依据当前显示的上下文弹出一个菜单。
菜单中能够有一些选项,比方删除,改动该项。这样的一般在ListView或GridView中常见。今天,我们就在这个例程中具体介绍怎样实现这个功能。
对ListView来说,我们仅仅须要对它的delegate做一些改动:
Component { id: listDelegate ListItem { id: delegateItem listView.width; height: units.gu(10) onPressAndHold: ListView.view.ViewItems.dragMode = !ListView.view.ViewItems.dragMode Image { id: pic height: parent.height - units.gu(1) 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) 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的菜单。
执行我们的应用:
整个项目的源代码在:https://github.com/liu-xiao-guo/contextmenu