【问题标题】:QML - ListView item which displays a menu on tapQML - ListView 项目,点击时显示菜单
【发布时间】:2023-12-17 09:59:01
【问题描述】:

我正在寻找一些关于在用户点击项目时在列表项目下方显示菜单的提示和指示。

如果我有这样的 ListModel:

ListModel {
    ListElement {
        name: "Bill Smith"
        number: "555 3264"
    }
    ListElement {
        name: "John Brown"
        number: "555 8426"
    }
    ListElement {
        name: "Sam Wise"
        number: "555 0473"
    }
}

然后是这样的 ListView:

Rectangle {
    width: 180; height: 200

    Component {
        id: contactDelegate
        Item {
            width: 180; height: 40
            Column {
                Text { text: '<b>Name:</b> ' + name }
                Text { text: '<b>Number:</b> ' + number }
            }
        }
    }

    ListView {
        anchors.fill: parent
        model: ContactModel {}
        delegate: contactDelegate
        highlight: Rectangle { color: "lightsteelblue"; radius: 5 }
        focus: true
    }
}

然后当用户点击一个项目时,我想显示一个菜单:

Menu {
    id: menu
    MenuItem { text: "item1" }
    MenuItem { text: "item2"; }
    MenuItem { text: "item3"; }
}

查看其他一些 QML 示例,我发现了一些添加 MouseArea 并根据窗口定位菜单的代码 - 菜单高度和宽度:

MouseArea {
    anchors.fill: parent
    onClicked: {
        menu.x = (window.width - menu.width) / 2
        menu.y = (window.height - menu.height) / 2
        menu.open();
    }
}

但是我正在努力让它工作,谁能指出我正确的方向?

【问题讨论】:

  • 你可以解释你想得到什么,你的解释可以有多种解释。
  • 我希望菜单位于被点击的列表项下方。就在它的正下方。
  • 你把MouseArea代码放在哪里了?

标签: qt qml qt5 qtquick2 qt-quick


【解决方案1】:

如果确定Menu的父级是ListView,那么只要通过mapToItem确定按下的item的相对位置即可:

Rectangle {
    width: 180; height: 200

    Component {
        id: contactDelegate
        Item {
            width: 180; height: 40
            Column {
                Text { text: '<b>Name:</b> ' + name }
                Text { text: '<b>Number:</b> ' + number }
            }

            MouseArea{
                anchors.fill: parent
                onClicked:  {
                    var pos = mapToItem(listView, 0, height)
                    menu.x = pos.x
                    menu.y = pos.y
                    menu.open()
                }
            }
        }
    }

    ListView {
        id: listView
        objectName: "list"
        anchors.fill: parent
        model: ContactModel{}
        delegate: contactDelegate
        focus: true

        Menu {
            id: menu
            MenuItem { text: "item1" }
            MenuItem { text: "item2"; }
            MenuItem { text: "item3"; }
        }

    }
}

完整的例子可以在下面的link找到。

【讨论】: