ListView steals taps from TapHandler regardless of declaration order. That is, the Rectangle, which is declared first, responds to a click, but not the ListView, which also lies below the TapHandler.
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Layouts 1.15
Window {
id: root
width: 640
height: 480
visible: true
color: tap.pressed ? "#6698D9" : "white"
title: qsTr("Hello World")
ColumnLayout {
anchors.fill: parent
Rectangle {
Layout.preferredHeight: text.height
Layout.fillWidth: true
color: "transparent"
border {
color: "blue"
width: 3
}
Text {
id: text
anchors.centerIn: parent
font.pointSize: 24
color: "red"
text: "some text"
}
}
ListView {
id: seriesView
Layout.fillWidth: true
Layout.fillHeight: true
orientation: ListView.Vertical
spacing: 5
clip: true
model: ["t1", "t2", "t3"]
delegate: Rectangle {
width: seriesView.width
height: childText.height
color: "transparent"
border {
color: "blue"
width: 3
}
Text {
id: childText
anchors.centerIn: parent
font.pointSize: 24
color: "green"
text: modelData
}
}
}
}
TapHandler {
id: tap
onTapped: console.log("Tapped root")
}
}
I also do not understand why the tap on the free area is not caught. It's about TapHandler. Not MouseArea.
I would like the TapHandler to catch clicks within the parent element (highlighted in red).
repo link: https://github.com/conelov/SO_qml_TapHandler_question
CodePudding user response:
Right now, because you use Layout.fillHeight: true
the ListView
extends to the entire bottom. This means the ListView
covers both the area covered by your delegates and the blank area.
ListView {
id: seriesView
Layout.fillWidth: true
Layout.fillHeight: true
}
As you observed, because ListView
gets the mouse events the TapHandler
will not get any.
Two things you can do to get the ListView
to cede mouse events to the TapHandler
. (1) you can declare additional TapHandler
s in the ListView
delegates. (2) you can reduce blank space of the ListView
.
Item {
Layout.fillWidth: true
Layout.fillHeight: true
ListView {
id: seriesView
width: parent.width
height: Math.min(parent.height, childrenRect.height)
delegate: Rectangle {
// ...
TapHandler { }
}
}
}
Here's a working example that implements the above.
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
Page {
id: root
background: Rectangle {
color: tap.pressed ? "#6698D9" : "white"
}
ColumnLayout {
anchors.fill: parent
Rectangle {
Layout.preferredHeight: text.height
Layout.fillWidth: true
color: "transparent"
border {
color: "blue"
width: 3
}
Text {
id: text
anchors.centerIn: parent
font.pointSize: 24
color: "red"
text: "some text"
}
}
Item {
Layout.fillWidth: true
Layout.fillHeight: true
ListView {
id: seriesView
width: parent.width
height: Math.min(parent.height, childrenRect.height)
orientation: ListView.Vertical
spacing: 5
clip: true
model: ["t1", "t2", "t3"]
delegate: Rectangle {
width: seriesView.width
height: childText.height
color: "transparent"
border {
color: "blue"
width: 3
}
Text {
id: childText
anchors.centerIn: parent
font.pointSize: 24
color: "green"
text: modelData
}
TapHandler {
}
}
}
}
}
TapHandler {
id: tap
onTapped: console.log("Tapped root")
}
}
You can Try it Online!
With all this effort to make TapHandler
work this way, it might be easier to simply use MouseArea { anchors.fill: parent}
instead. It wasn't clear why you needed to use TapHandler
?