Qt QML ComboBox覆盖轮事件

时间:2015-10-12 08:54:01

标签: qt combobox qml qt5.5

有没有办法覆盖ComboBox MouseArea来忽略wheel事件而不是改变当前索引? ComboBox本身无法改变车轮焦点行为。到目前为止,我试图用以下代码覆盖CB MouseArea的onWheel:

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()
      }
    }
  }
}

但是我得到了

  

TypeError:无法分配给只读属性“wheel”

是否有人能够在Qml中禁用ComboBox上的滚轮事件?

//编辑

例如在Slider控件中我能够像这样删除滚轮事件处理:

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()
      }
    }
  }
}

但是在滑块中,WheelArea不负责处理“点击”事件。

5 个答案:

答案 0 :(得分:2)

目前无法实现,因为ComboBox不是来自MouseArea,而是FocusScope,它不支持这类事件。

最近在一项建议中提到了类似的问题:

Disable mouse wheel scroll event on QtQuick.Controls

如果您采用hacky方法,那么您似乎唯一的选择就是将ComboBox.qml应用补丁删除onWheel处理程序:

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();
-            }
-        }
     }

另一个不涉及修改Qt代码的替代方案是在 MouseArea上方添加中间ComboBox ,然后以某种方式仅转发特定事件到ComboBox MouseArea。或者,创建一个等效的自定义C ++项。你可以通过这种方式获得更多控制权。

答案 1 :(得分:2)

您可以将MouseArea放在ComboBox和钢轮事件上。

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;
        }
    }
}

答案 2 :(得分:1)

确定。在黑客入侵之后,我设法提供了对我来说可接受的解决方案,但在某些情况下可能会引入一些回归。压榨和悬停的属性不再可用

import QtQuick.Controls.Private 1.0

ComboBox {
  Component.onCompleted: {
    for (var i = 0; i < combobox_ctrl.children.length; ++i) {
      if (combobox_ctrl.children[i].hasOwnProperty('onWheel') && combobox_ctrl.children[i] !== mouseArea) {
        combobox_ctrl.children[i].destroy()
      }
    }
  }

  MouseArea {
    id: mouseArea
    anchors.fill: parent

    onPressed: {
      if (combobox_ctrl.activeFocusOnPress)
        forceActiveFocus()
      if (!Settings.hasTouchScreen)
        combobox_ctrl.__popup.toggleShow()
    }

    onClicked: {
      if (Settings.hasTouchScreen)
        combobox_ctrl.__popup.toggleShow()
    }
  }
}

这样我们就可以模仿最初位于ComboBox内部的鼠标区域。 Popup显示为原样(至少我还没有看到任何回归)。但是现在有两个属性无法使用

答案 3 :(得分:1)

我在此帖后面创建了一个名为turbolinks的单独文件,其中包含以下代码:https://stackoverflow.com/a/33080217/969016

现在我可以在我不希望鼠标滚动更改值的地方使用$( document ).on('turbolinks:load', function() { // Do your code }) 作为组件而不是NonScrollingComboBox.qml

NonScrollingComboBox

用法:

ComboBox

答案 4 :(得分:0)

这似乎只适用于Qt Quick Controls 1 ComboBox。在Qt Quick Controls 2 ComboBox上,默认情况下不启用滚轮鼠标事件,可以通过将属性wheelEnabled设置为true来手动启用(在基类Control中记录)。此外,组合框不会对鼠标事件保持“关注”,因此只需输入它们就可以在其他鼠标区域自由使用。