WheelHandler event on active focus and not based on cursor
-
wrote on 4 Apr 2025, 16:48 last edited by
Qt Version 6.8.3
Hi all,
I am working Qt Quick Application with a couple of custom Items and QtQuick controls. I would like to handle wheel events when the item has activeFocus. What I would like to achieve is something like this:- A user clicks on an item to give it focus
- While the item is focused, I want to receive wheel events — even if the mouse isn't hovering over it
- Once focus is lost, wheel events should no longer be processed by that item
This should be the intended end goal because I need to run the application on a Linux-based embedded display that supports touch input and includes a rotary encoder functioning as a mouse wheel.
I have looked into WheelHandlers so far and it seems to work only when the item contains mouse. I have also tried creating a global WheelHandler, and specify the target to activeFocusItem of my window but no luck with it. This is a minimal reproducible example of my application
import QtQuick import QtQuick.Layouts import QtQuick.Controls.Material Window { id: root width: 1280 height: 768 visible: true title: qsTr("App") property int myGlobalVar: 50 property list<color> colors: ["red", "blue", "green"] onActiveFocusItemChanged: { console.log("Active Focus is now with:", root.activeFocusItem, " ", (root.activeFocusItem ? root.activeFocusItem.objectName : "null")) } Item { anchors.fill: parent z: -1 Text { id: globalVarDisplay text: root.myGlobalVar font.pixelSize: 60 anchors.horizontalCenter: parent.horizontalCenter y: 64 } GridLayout { rows: 1 columns: 3 anchors.top: globalVarDisplay.bottom anchors.bottom: parent.bottom anchors.left: parent.left anchors.right: parent.right anchors.margins: 32 SpinBox { id: spin value: 50 from: 0 to: 100 stepSize: 1 z: 10 wheelEnabled: true hoverEnabled: false Layout.alignment: Qt.AlignVCenter || Qt.AlignHCenter WheelHandler { acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad enabled: spin.activeFocus onWheel: wheel => { console.log("wheel spinbox event here") wheel.accepted = false } } } Button { id: takeAwayFocus text: "Click to take away focus" Layout.alignment: Qt.AlignVCenter || Qt.AlignHCenter } Rectangle { id: focusItem width: 300 height: 300 Layout.alignment: Qt.AlignVCenter || Qt.AlignHCenter focus: true z: 10 property int colorId: 1 color: root.colors[colorId] MouseArea { anchors.fill: parent cursorShape: Qt.OpenHandCursor hoverEnabled: false onClicked: { focusItem.forceActiveFocus() } } WheelHandler { acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad enabled: focusItem.activeFocus onWheel: wheel => { console.log("rectangle wheel event") focusItem.colorId = (focusItem.colorId + 1) % 3 wheel.accepted = true } } } } WheelHandler { acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad target: root.activeFocusItem onWheel: wheel => { console.log("Parent item wheel event") wheel.accepted = false //Pass to items lower in the stacking order.. } } } }
Is there a way to do this in pure QML, or should I override event handling in C++? Any ideas or workarounds would be really appreciated as I am fairly new to Qt
Thanks in advance
1/1