Qml 中的那些坑(五)---MouseArea 上的 Li

【写在前面】

最近在 Qml 中使用 MouseArea 时发现了一个奇怪的现象:

位于 MouseArea 上的 ListView 在处理了滚轮事件的情况下进行滚轮,下面的 MouseArea 却在某些情况下接收到了这个事件。

按照直觉,ListView 明明有内部的滚轮事件处理,应该阻止事件向下传递才对,然而此时的情况却出乎意料,因此在此记录并附上解决方案。


【正文开始】

首先,我们来看一个很简单的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
javascript复制代码import QtQuick 2.15
import QtQuick.Window 2.15

Window {
width: 640
height: 480
visible: true
title: qsTr("Hello World")

Rectangle {
id: scaledRect
width: 100
height: 100
anchors.centerIn: parent
color: "red"
}

MouseArea {
id: mouseArea1
anchors.fill: parent
onWheel: (wheel) => {
if (wheel.angleDelta.y > 0) scaledRect.scale += 0.1;
else if (wheel.angleDelta.y < 0) scaledRect.scale -= 0.1;
print("mouseArea1 wheel event!");
}
}

ListView {
id: listView
width: parent.width * 0.5
height: parent.height * 0.5
anchors.centerIn: parent
clip: true
model: 100
spacing: 5
delegate: Rectangle {
width: listView.width
height: 20
color: "#8000ff00"

Text {
anchors.centerIn: parent
text: index
}
}
}
}

按道理,我在最顶层的ListView 上滚动鼠标,应当不会影响到下面的的红色方块,然而,事实并非如此:

可以看到,某些时候我在 ListView上滑动滚轮,底层的 MouseArea 也会接收并处理滚轮事件。

一开始,我以为是 ListView 的 spaing 属性( 代理项的间隔 )导致滚轮事件穿透,然而去掉后并没有卵用,问题仍然没有解决。

不管怎样,这是一个相当坑爹的 BUG( 也许不是,但至少影响到我了 ),那么必须要处理好它。

这里我用了一点奇怪的写法,但相当有用,方法是增加一个 MouseArea 并处理其滚轮事件( 自己处理总不会穿透了吧!):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
javascript复制代码    MouseArea {
width: parent.width * 0.5
height: parent.height * 0.5
anchors.centerIn: parent
onWheel: (wheel) => wheel.accepted = true;

ListView {
id: listView
anchors.fill: parent
clip: true
model: 100
spacing: 5
delegate: Rectangle {
width: listView.width
height: 20
color: "#8000ff00"

Text {
anchors.centerIn: parent
text: index
}
}
}
}

没错,将 ListView 置于一个 MouseArea 内 即可解决问题。


【结语】

最后,我发现 Qt6 仍有这种情况,因此需要大家格外注意。

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%