如何在QML应用中创建一个Context Menu

来源:互联网 发布:上海软件编程培训机构 编辑:程序博客网 时间:2024/06/05 05:10

我们在很多的系统中看见可以在屏幕的一个地方长按,然后就可以根据当前显示的上下文弹出一个菜单。菜单中可以有一些选项,比如删除,修改该项。这种一般在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的菜单。


运行我们的应用:


  


整个项目的源码在:https://github.com/liu-xiao-guo/contextmenu


0 0