首页 > 解决方案 > QML - 防止 MouseArea 的 positionChanged 信号在 ScrollView 中传播

问题描述

这篇文章是我已经在 Qt 论坛上发送的消息的副本,但我无法得到答案。您可以在此处找到原始帖子:https ://forum.qt.io/topic/113890/prevent-mousearea-s-positionchanged-signal-to-propagate-in-scrollview/4

如果链接失效,所有内容都复制到下面:


我正在尝试处理 ScrollView 中的 MouseArea 中的 positionChanged 信号(以创建一种拖放效果)。

我的问题是鼠标移动了一小段距离后,父 ScrollView 似乎获得了焦点(出现了滚动条),我停下来接收 positionChanged 信号。

目标是接收 positionChanged 信号(即使鼠标离开我的 MouseArea 并在 ScrollView 上,只要我的鼠标左键保持按下状态)而不将信号传播到 ScrollView。

我有 3 个单独的例子。这是一个简单的 QML 应用程序,应该很容易运行。前两个例子有效。第三个不起作用。

什么是“工作”:

  1. 在 MouseArea 上按下鼠标按钮
  2. 在不释放按钮的情况下移动鼠标
  3. 在您释放鼠标按钮之前,无论您在屏幕上的哪个位置,记录坐标的消息都不应停止打印。

对于第三个示例,我获取日志,直到鼠标移动太多并且所有更新都停止。

  1. 只有 ScrollView(有效)
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12

ApplicationWindow{
    id: root
    visible: true
    width: 1200
    height: 600

    ScrollView {
        clip: true
        anchors.fill: parent

        MouseArea {
            width: 300
            height: 300

            onPositionChanged: {
                console.log('Moved', mouseX, mouseY)
            }
        }
    }
}
  1. 只有 ColumnLayout (作品)
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12

ApplicationWindow{
    id: root
    visible: true
    width: 1200
    height: 600

    ColumnLayout {
        MouseArea {
            width: 300
            height: 300

            onPositionChanged: {
                console.log('Moved', mouseX, mouseY)
            }
        }
    }
}
  1. ScrollView 内的 ColumnLayout(不起作用)
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12

ApplicationWindow {
    id: root
    visible: true
    width: 1200
    height: 600

    ScrollView {
        clip: true
        anchors.fill: parent

                // note: It does not work for ColumnLayout, Column, Row or RowLayout. If I use a Item here, it works
        ColumnLayout {
            MouseArea {
                width: 300
                height: 300

                onPositionChanged: {
                    console.log('Moved', mouseX, mouseY)
                }
            }
        }
    }
}

您可以在此处找到该行为的视频:https ://i.imgur.com/rIlWnhu.mp4

  1. 我按下并释放鼠标而不移动:我正确获得了按下和释放的事件
  2. 我按下并移动鼠标:我得到按下事件,移动事件,然后它停止。不再有移动或释放事件。
  3. 我按下并移动鼠标而不会离我按下鼠标的位置太远:它可以工作,直到我太远注意:我没有收到任何 Released 或 Exited 事件,但containsPressed属性已正确更新(即:当我不再接收事件,其值为 false)。这是我用来显示“鼠标按下”文本的属性。

这是我对 ScrollView/ColumnLayout 组合做错了什么还是 Qt 错误?

标签: qtqml

解决方案


在您的第三个示例中将此添加到您的 MouseArea:

    preventStealing: true

有关更多信息,请参阅:

https://doc.qt.io/qt-5/qml-qtquick-mousearea.html#preventStealing-prop


推荐阅读