Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Qt QML ComboBox override wheel events

Is there any way to override ComboBox MouseArea to ignore wheel event instead of changing current index? ComboBox itself has no option to change wheel focus behaviour. So far I've tried to override onWheel from CB MouseArea with code like this:

ComboBox {
  Component.onCompleted: {
    for (var i = 0; i < combobox_ctrl.children.length; ++i) {
      console.log(combobox_ctrl.children[i])
      console.log(combobox_ctrl.children[i].hasOwnProperty('onWheel'))

      if (combobox_ctrl.children[i].hasOwnProperty('onWheel')) {
        console.log(combobox_ctrl.children[i]['onWheel'])
        combobox_ctrl.children[i]['onWheel'] = function() { console.log("CB on wheel!") }
        //combobox_ctrl.children[i]onWheel = function() { console.log("CB on wheel!") 
        //combobox_ctrl.children[i].destroy()
      }
    }
  }
}

But I get

TypeError: Cannot assign to read-only property "wheel"

Did anyone was able to disable wheel events on ComboBox in Qml?

// EDIT

for example in Slider control I was able to remove wheel event handling like this:

Slider {
  Component.onCompleted: {
    for (var i = 0; i < slider.children.length; ++i) {
      console.log(slider.children[i])
      if (slider.children[i].hasOwnProperty("onVerticalWheelMoved") && slider.children[i].hasOwnProperty("onHorizontalWheelMoved")) {
        console.log("Found wheel area!")
        slider.children[i].destroy()
      }
    }
  }
}

But in slider WheelArea is not responsible for handling "click" events.

like image 435
Kamil Klimek Avatar asked Sep 10 '25 22:09

Kamil Klimek


2 Answers

You can place MouseArea over ComboBox and steal the wheel event.

ComboBox {
    anchors.centerIn: parent
    model: [ "Banana", "Apple", "Coconut" ]
    MouseArea {
        anchors.fill: parent
        onWheel: {
            // do nothing
        }
        onPressed: {
            // propogate to ComboBox
            mouse.accepted = false;
        }
        onReleased: {
            // propogate to ComboBox
            mouse.accepted = false;
        }
    }
}
like image 132
Meefte Avatar answered Sep 13 '25 13:09

Meefte


It's not currently possible, as ComboBox is not derived from MouseArea, but FocusScope, which has no support for these kinds of events.

A similar problem was mentioned in a suggestion recently:

Disable mouse wheel scroll event on QtQuick.Controls


If you're after a hacky way of doing it, it seems like the only option you have left is to apply a patch to ComboBox.qml that removes the onWheel handler:

diff --git a/src/controls/ComboBox.qml b/src/controls/ComboBox.qml
index 4e29dfe..3413cac 100644
--- a/src/controls/ComboBox.qml
+++ b/src/controls/ComboBox.qml
@@ -407,13 +407,6 @@ Control {
                 popup.toggleShow()
             overridePressed = false
         }
-        onWheel: {
-            if (wheel.angleDelta.y > 0) {
-                __selectPrevItem();
-            } else if (wheel.angleDelta.y < 0){
-                __selectNextItem();
-            }
-        }
     }

Another alternative that doesn't involve modifying Qt code would be to add an intermediate MouseArea above ComboBox's, and then somehow only forward specific events through to ComboBox's MouseArea. Or, create a custom C++ item that does the equivalent. You may have more control that way.

like image 29
Mitch Avatar answered Sep 13 '25 15:09

Mitch