QML:ListView 中的鼠标滚轮事件传播

QML: Mouse wheel event propagation in ListView

ListView 在鼠标滚轮上滚动时出现奇怪的情况。具有与此类似的项目结构:

MainAppWindow {

    // Some  zoomable map item
    Map {
        anchors.fill: parent
    }

    PopupMenu { // Simple Rectangle item
      anchors.top: parent.top
      width: 200
      height: parent.height / 2
      z: parent.z + 1

      ListView {
        anchors.fill: parent
        clip: true
        ...
        delegate: Item {
          ...
            MouseArea {
                anchors.fill: parent
                onClick: {
                    someHandler()
                }
            }
        }
      }
    }
}

ListViewvertical 滚动工作并且滚动得很好,直到它停止在边界(顶部或底部 - 任何)在这个鼠标事件开始传播到底层并且 ZoomableMap 开始缩放之后,这不是我们想要的:只有当 PopupMenu 不可见时才应该传播到那里。添加

                onWheel: wheel.accepted = true

into MouseArea inside ListView delegate 可以部分解决问题 - 它禁用滚轮并仅允许通过拖动内容进行滚动。但是最好也允许通过滚轮滚动。 PopupMenu 中的 MouseArea 挡住滚轮并在 ListView 中完全拖动 - 也无济于事。

那么这是什么问题,如何解决?还是我们这里做错了什么?

需要将另一个 MouseArea 添加到 PopupMenu 中,它会阻止所有鼠标事件,默认情况下禁用,只有在弹出窗口可见时才启用它(可选):

enabled: popupMenu.visible

MainAppWindow {

    // Some  zoomable map item
    Map {
        id: map
        anchors.fill: parent
    }

    PopupMenu { // Simple Rectangle item
        id: popupMenu
        anchors.top: parent.top
        width: 200
        height: parent.height / 2
        z: parent.z + 1

        MouseArea {
            id: mapMouseArea
            anchors.fill: parent
            enabled: popupMenu.visible
            preventStealing:true
            hoverEnabled:   true
            onWheel:        { wheel.accepted = true; }
            onPressed:      { mouse.accepted = true; }
            onReleased:     { mouse.accepted = true; }
        }

        ListView {
            anchors.fill: parent
            clip: true
            ...
            delegate: Item {
                ...
                MouseArea {
                    anchors.fill: parent
                    onClick: {
                        someHandler()
                    }
                }
            }
        }
    }
}

Note: however this solution does not work if ListView (or any other control) is a Map descendant item: item dragging causes map panning. To make it work need to make it at least sibling.