Qt QML ComboBox 覆盖滚轮事件

问题描述 投票:0回答:5

有没有办法覆盖 ComboBox MouseArea 以忽略滚轮事件而不是更改当前索引? 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 {
  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 不负责处理“点击”事件。

qt combobox qml qt5.5
5个回答
4
投票

您可以将

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
投票

目前不可能,因为

ComboBox
不是源自
MouseArea
,而是源自
FocusScope
,它不支持此类事件。

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

在 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
above
ComboBox
,然后以某种方式仅将特定事件转发到
ComboBox
MouseArea
。或者,创建一个执行等效操作的自定义 C++ 项。这样你可能会有更多的控制权。


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

这样我们就可以模仿最初位于组合框内的鼠标区域。弹出窗口按原样显示(至少我还没有看到任何回归)。但是现在有两个属性无法访问


1
投票

我在本文后面创建了一个名为

NonScrollingComboBox.qml
的单独文件,其中包含以下代码:https://stackoverflow.com/a/33080217/969016

现在我可以在不希望鼠标滚动更改值的地方使用

NonScrollingComboBox
作为组件,而不是
ComboBox

import QtQuick 2.0
import QtQuick.Controls 1.4

ComboBox {
    id: combobox_ctrl
    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()
            combobox_ctrl.__popup.toggleShow()
        }

        onClicked: {
            combobox_ctrl.__popup.toggleShow()
        }
    }
}

用途:

NonScrollingComboBox {
    anchors.verticalCenter: parent.verticalCenter
    model: ["item one", "item 2"]
}

0
投票

这似乎仅适用于Qt Quick Controls 1 ComboBox。在 Qt Quick Controls 2 ComboBox 上,默认情况下不启用滚轮鼠标事件,可以通过将属性

wheelEnabled
设置为 true 来手动启用(在基类 Control 中记录)。此外,组合框不会“聚焦”鼠标事件,因此您只需输入其他鼠标区域即可自由使用滚轮。

© www.soinside.com 2019 - 2024. All rights reserved.