当鼠标移到 ComboBox 或 SpinBox Item 上时如何防止焦点改变

How to prevent focus change when mouse goes on ComboBox or SpinBox Item

我使用 ListView 并且在这个 ListView 的每个 Item 中,我有一个 ComboBoxSpinBox

我的问题是,当我想 scroll 我的 ListView 时,如果我的 mouse 继续 ComboBoxSpinBox 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.xQtQuick.Controls 2.x 都放在一个文件中很容易,方法是使用别名导入它们。

深入研究 QtQuick.Controls 1.4 的来源,我们也可以找到一个 hacky 解决方案。

相关文件:

我们可以看到,一个SpinBox就是一个ControlSpinBox 有一个 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 } )
}

但是我们需要找到一些方法来再次失去这种关注。