有没有办法覆盖 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 不负责处理“点击”事件。
您可以将
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;
}
}
}
目前不可能,因为
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++ 项。这样你可能会有更多的控制权。
好的。经过一番修改后,我设法找到了我可以接受的解决方案,但在某些情况下可能会引入一些回归。按下和悬停属性不再可用
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()
}
}
}
这样我们就可以模仿最初位于组合框内的鼠标区域。弹出窗口按原样显示(至少我还没有看到任何回归)。但是现在有两个属性无法访问
我在本文后面创建了一个名为
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"]
}
这似乎仅适用于Qt Quick Controls 1 ComboBox。在 Qt Quick Controls 2 ComboBox 上,默认情况下不启用滚轮鼠标事件,可以通过将属性
wheelEnabled
设置为 true 来手动启用(在基类 Control 中记录)。此外,组合框不会“聚焦”鼠标事件,因此您只需输入其他鼠标区域即可自由使用滚轮。