【问题标题】:QML: Mouse wheel event propagation in ListViewQML:ListView 中的鼠标滚轮事件传播
【发布时间】:2019-11-20 23:56:45
【问题描述】:

ListView 在鼠标滚轮上滚动时遇到奇怪的情况。具有类似于此的 Items 结构:

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()
                }
            }
        }
      }
    }
}
带有 vertical 滚动的

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

                onWheel: wheel.accepted = true

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

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

【问题讨论】:

  • PopupMenu::visible == true 时可以在ZoomableMap 中禁用缩放/鼠标交互吗? (当然,弹出窗口需要id。)理想情况下,ZoomableMap 会有一些属性......在这种情况下,它可能是最简单的选择。
  • @MaximPaperno 是的,这可能是解决方案。谢谢!需要在ZoomableMap 中添加另一个MouseArea,它会阻止所有鼠标事件,默认情况下是禁用的,只有在弹出窗口可见时才启用它。 ID当然存在。
  • 酷,肯定会比关注Flickable code 更容易... :-) 实际上我没有看到任何 API(甚至是 hack)可以让 flickable 继续“窃取”(滚动完成后抓住)鼠标。
  • @MaximPaperno 是的,非常奇怪的行为甚至是 Qt 错误。
  • 你在开玩笑吧,QGC?多么可笑的巧合!我是very familiar,有一个旧叉子... :-)

标签: qt qml qt5 qtquick2 qtquickcontrols2


【解决方案1】:

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

启用: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()
                    }
                }
            }
        }
    }
}

注意: 但是,如果 ListView(或任何其他控件)是 Map 后代项目,则此解决方案不起作用:项目拖动会导致地图平移。要使其工作,至少需要使其成为兄弟。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-03
    • 2017-12-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多