怎样在QML应用中创建一个Context Menu

我们在非常多的系统中看见能够在屏幕的一个地方长按,然后就能够依据当前显示的上下文弹出一个菜单。

菜单中能够有一些选项,比方删除,改动该项。这样的一般在ListViewGridView中常见。今天,我们就在这个例程中具体介绍怎样实现这个功能。


对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


原文地址:https://www.cnblogs.com/jzssuanfa/p/7364234.html