Qt QML中ListView设置header后带MouseArea的delegate无法滑动问题
问题根因
你遇到的是Qt Quick 2.15(对应Qt 5.15版本,你描述的Qt 2.15为笔误)中ListView使用OverlayHeader模式时的事件传递逻辑问题:
- 你给header设置了
z:2,和delegate中MouseArea的z值持平,Overlay模式下的header会优先拦截其垂直覆盖范围内的所有鼠标事件,哪怕header本身没有设置MouseArea、且宽度只有窗口一半,它的垂直投影区域的事件都会被拦截,不会传递给下方的ListView视图处理,也就无法触发滑动。 - 这也解释了你测试到的现象:header多高,下方每个delegate顶部对应高度的区域都无法滑动,本质是这些区域都属于header的垂直事件拦截范围。
解决方案
如果你需要保留header悬浮在列表上方的Overlay效果,只需要给header加一个透传所有事件的MouseArea即可,让header区域的触摸/鼠标事件直接传递给下层的ListView处理滑动逻辑。
修正后完整代码
import QtQuick 2.15 import QtQuick.Window 2.15 import QtQuick.Controls 2.15 Window { id: root width: 640 height: 600 visible: true ListView { id: list anchors.fill: parent model: 20 delegate: Rectangle { signal clicked(); implicitHeight: 70 width: root.width MouseArea { anchors.fill: parent z: 2 onClicked: console.log("clicked"); } Text { anchors.centerIn: parent text: "text" } } headerPositioning: ListView.OverlayHeader header: Rectangle { z: 2 implicitHeight: 100 implicitWidth: root.width / 2 color: "blue" // 新增透传事件的MouseArea MouseArea { anchors.fill: parent propagateComposedEvents: true onPressed: mouse.accepted = false } } } }
如果你不需要header悬浮覆盖在列表内容上,可以直接把headerPositioning改成默认的ListView.InlineHeader,也可以解决该问题,此时header会作为列表的第一个元素跟随滚动,不会拦截下方delegate的事件。
内容的提问来源于stack exchange,提问作者splaytreez
相关产品推荐
相关产品推荐

