当鼠标移到 ComboBox 或 SpinBox Item 上时如何防止焦点改变
How to prevent focus change when mouse goes on ComboBox or SpinBox Item
我使用 ListView
并且在这个 ListView
的每个 Item
中,我有一个 ComboBox
或 SpinBox
。
我的问题是,当我想 scroll
我的 ListView
时,如果我的 mouse
继续 ComboBox
或 SpinBox
, focus
将更改, scroll
现在将在此 Item
而不是列表 上。
我希望只有在单击这些项目时才会将焦点设置在它们上。
代码示例:
import QtQuick.Controls 1.4
ListView {
id: list
ScrollBar.vertical: ScrollBar {}
...
model: DelegateModel {
id:delegate
model: myModel
delegate : Rectangle {
id: rect
...
SpinBox {
id: spin
...
}
}
}
}
我该如何继续?
这是旧 QtQuick.Controls 1.x
组件的一个常见问题,它们会贪婪地获取鼠标事件。据我所知,没有正式的方法来防止这种情况。
你找到了一个解决方案,关于如何用 MouseArea
覆盖这样一个组件(在本例中是 Slider
),以防止这种不当行为。
或者您可以切换到新的 QtQuick.Controls 2.x
-Spinbox。由于它具有不同的默认外观,您可能需要对其进行调整,使其看起来(更)类似于旧外观。 您可以找到有关如何执行此操作的说明。
请记住,将 QtQuick.Controls 1.x
和 QtQuick.Controls 2.x
都放在一个文件中很容易,方法是使用别名导入它们。
深入研究 QtQuick.Controls 1.4
的来源,我们也可以找到一个 hacky 解决方案。
相关文件:
- http://code.qt.io/cgit/qt/qtquickcontrols.git/tree/src/controls/SpinBox.qml
- http://code.qt.io/cgit/qt/qtquickcontrols.git/tree/src/controls/Private/Control.qml
我们可以看到,一个SpinBox
就是一个Control
。 SpinBox
有一个 child MouseArea
,它处理 onWheel
事件。我们将禁用此 MouseArea
。要访问它,我们需要知道 SpinBox.children
中的索引。我们在 Control
中看到有两个 Loader
作为 children (索引 0 和 1)。在 SpinBox
中,我们在 MouseArea
之前还有另外两个 children(索引 2 和 3)-> 所以我们需要设置 idOfSpinBox.children[4].enabled = false
来禁用 wheel-sensitivity。
import QtQuick 2.7
import QtQuick.Controls 1.4
ApplicationWindow {
id: root
visible: true
width: 800
height: 600
ListView {
model: 20
width: 100
height: 200
delegate: SpinBox {
Component.onCompleted: children[4].enabled = false
}
}
}
或者如果我们想要启用滚轮,当 SpinBox
被点击时,我们使用:
delegate: SpinBox {
id: spinBox
Component.onCompleted: children[4].enabled = Qt.binding(function() { return spinBox.activeFocus } )
}
但是我们需要找到一些方法来再次失去这种关注。
我使用 ListView
并且在这个 ListView
的每个 Item
中,我有一个 ComboBox
或 SpinBox
。
我的问题是,当我想 scroll
我的 ListView
时,如果我的 mouse
继续 ComboBox
或 SpinBox
, focus
将更改, scroll
现在将在此 Item
而不是列表 上。
我希望只有在单击这些项目时才会将焦点设置在它们上。
代码示例:
import QtQuick.Controls 1.4
ListView {
id: list
ScrollBar.vertical: ScrollBar {}
...
model: DelegateModel {
id:delegate
model: myModel
delegate : Rectangle {
id: rect
...
SpinBox {
id: spin
...
}
}
}
}
我该如何继续?
这是旧 QtQuick.Controls 1.x
组件的一个常见问题,它们会贪婪地获取鼠标事件。据我所知,没有正式的方法来防止这种情况。
MouseArea
覆盖这样一个组件(在本例中是 Slider
),以防止这种不当行为。
或者您可以切换到新的 QtQuick.Controls 2.x
-Spinbox。由于它具有不同的默认外观,您可能需要对其进行调整,使其看起来(更)类似于旧外观。
请记住,将 QtQuick.Controls 1.x
和 QtQuick.Controls 2.x
都放在一个文件中很容易,方法是使用别名导入它们。
深入研究 QtQuick.Controls 1.4
的来源,我们也可以找到一个 hacky 解决方案。
相关文件:
- http://code.qt.io/cgit/qt/qtquickcontrols.git/tree/src/controls/SpinBox.qml
- http://code.qt.io/cgit/qt/qtquickcontrols.git/tree/src/controls/Private/Control.qml
我们可以看到,一个SpinBox
就是一个Control
。 SpinBox
有一个 child MouseArea
,它处理 onWheel
事件。我们将禁用此 MouseArea
。要访问它,我们需要知道 SpinBox.children
中的索引。我们在 Control
中看到有两个 Loader
作为 children (索引 0 和 1)。在 SpinBox
中,我们在 MouseArea
之前还有另外两个 children(索引 2 和 3)-> 所以我们需要设置 idOfSpinBox.children[4].enabled = false
来禁用 wheel-sensitivity。
import QtQuick 2.7
import QtQuick.Controls 1.4
ApplicationWindow {
id: root
visible: true
width: 800
height: 600
ListView {
model: 20
width: 100
height: 200
delegate: SpinBox {
Component.onCompleted: children[4].enabled = false
}
}
}
或者如果我们想要启用滚轮,当 SpinBox
被点击时,我们使用:
delegate: SpinBox {
id: spinBox
Component.onCompleted: children[4].enabled = Qt.binding(function() { return spinBox.activeFocus } )
}
但是我们需要找到一些方法来再次失去这种关注。