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 TapHandlers 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?



