Reputation: 33
I want to implement deselecting the current selection by clicking outside of the GridView items. The following code works fine in Qt5. However,the click event cannot be obtained in Qt6.
import QtQuick
import QtQuick.Controls
ApplicationWindow {
id: root
width: 640
height: 480
visible: true
title: qsTr("Hello World")
ListModel {
id: listModel
ListElement {
name: "Jim Williams"
}
ListElement {
name: "John Brown"
}
ListElement {
name: "Bill Smyth"
}
ListElement {
name: "Sam Wise"
}
}
GridView {
id: gridView
anchors.fill: parent
cellWidth: 80
cellHeight: 80
model: listModel
MouseArea {
z: -1
anchors.fill: parent
onClicked: {
console.log("out clicked!")
gridView.currentIndex = -1
}
}
delegate: Item {
id: wrapper
width: gridView.cellWidth
height: gridView.cellHeight
Rectangle {
anchors.fill: parent
anchors.margins: 4
color: wrapper.GridView.isCurrentItem ? "#009688" :"#3d3d3d"
Text {
anchors.fill: parent
color: "white"
text: name
}
}
MouseArea {
anchors.fill: parent
onClicked: {
gridView.currentIndex = index
}
}
}
}
}
In Qt5, I set the z of the first MouseArea to -1, which can achieve the effect I want. But this method is invalid in Qt6 and cannot respond to the clicked event of the first MouseArea. What should I do in Qt6?
Upvotes: 0
Views: 287
Reputation: 25871
This is one of the weird places where TapHandler
works better than MouseArea
. By defining a TapHandler
inside your GridView
you will be notified when you are interacting in an area that's in your GridView
but not on any of your delegates
. I also move the MouseArea
to inside your Rectangle
so even the white edges between the delegates
is now clicking thru to the TapHandler
.
import QtQuick
import QtQuick.Controls
Page {
ListModel {
id: listModel
ListElement { name: "Jim Williams" }
ListElement { name: "John Brown" }
ListElement { name: "Bill Smyth" }
ListElement { name: "Sam Wise" }
}
GridView {
id: gridView
anchors.fill: parent
cellWidth: 80
cellHeight: 80
model: listModel
TapHandler {
onTapped: {
console.log("out clicked!")
gridView.currentIndex = -1
}
}
delegate: Item {
id: wrapper
width: gridView.cellWidth
height: gridView.cellHeight
Rectangle {
anchors.fill: parent
anchors.margins: 4
color: wrapper.GridView.isCurrentItem ? "#009688" :"#3d3d3d"
Text {
anchors.fill: parent
color: "white"
text: name
}
MouseArea {
anchors.fill: parent
onClicked: {
gridView.currentIndex = index
}
}
}
}
}
}
You can Try it Online!
Upvotes: 1
Reputation: 796
You can use just on mouse handler in the GridView and handle selections there. First you map the mouse position to the GridView coordinate system. Then you lookup the index at this position.
GridView {
id: gridView
anchors.fill: parent
cellWidth: 80
cellHeight: 80
model: listModel
MouseArea {
anchors.fill: parent
onClicked: (mouse) => {
console.log("grid clicked!");
let posInGridView = Qt.point(mouse.x, mouse.y)
let posInContentItem = mapToItem(gridView.contentItem, posInGridView)
let index = gridView.indexAt(posInContentItem.x, posInContentItem.y)
gridView.currentIndex = index;
}
}
delegate: Item {
id: wrapper
width: gridView.cellWidth
height: gridView.cellHeight
Rectangle {
anchors.fill: parent
anchors.margins: 4
color: wrapper.GridView.isCurrentItem ? "#009688" :"#3d3d3d"
Text {
anchors.fill: parent
color: "white"
text: name
}
}
}
}
Upvotes: 0