【问题标题】:Disable mouse wheel for QML Slider禁用 QML Slider 的鼠标滚轮
【发布时间】:2016-12-21 12:26:05
【问题描述】:

我希望能够使用鼠标滚轮(或触摸板上的两根手指)滚动Flickable而不更改它可能包含的Sliders

示例代码和结果应用程序:

import QtQuick 2.7
import QtQuick.Window 2.2
import QtQuick.Controls 1.4

ApplicationWindow {
    id: rootWindow

    visible: true
    width: 400
    height: 200
    title: qsTr("Hello World")

    ScrollView {
        anchors.fill: parent
        flickableItem.flickableDirection: Flickable.VerticalFlick

        Column {
            Repeater {
                model: 40
                Slider {
                    width: rootWindow.width * 0.9
                }
            }
        }
    }
}

过去好像有一些attempt to fix this,但没有成功。

编辑:这仅与Controls 1.x 有关,因为从 2.0 版本开始,控件似乎没有此问题。

【问题讨论】:

  • 您尝试修复了吗? (将Slider.wheelarea.enabled 的值设置为false。)
  • @maxik wheelareaSlider 组件无法从外部访问。应该可以通过编辑Qt的Slider的源来改变它,但恐怕我也做不到。
  • 为什么要使用已弃用的 QtQuick.Controls 1.4 而不是 QtQuick.Controls 2.0?

标签: qt qml qtquick2 qtquickcontrols


【解决方案1】:

您可以将MouseAreas 放在滑块上以窃取鼠标滚轮事件。

类似这样的:

import QtQuick 2.7
import QtQuick.Window 2.2
import QtQuick.Controls 1.4

ApplicationWindow {
    id: rootWindow

    visible: true
    width: 400
    height: 200
    title: qsTr("Hello World")

    ScrollView {
        id: _scrollview
        anchors.fill: parent
        flickableItem.flickableDirection: Flickable.VerticalFlick

        Column {
            Repeater {
                model: 40
                Slider {
                    width: rootWindow.width * 0.9
                    property int scrollValue: 10

                    MouseArea {
                            anchors.fill: parent
                            onWheel: {
                                //check if mouse is scrolling up or down
                                if (wheel.angleDelta.y<0){
                                    //make sure not to scroll too far
                                    if (!_scrollview.flickableItem.atYEnd)
                                            _scrollview.flickableItem.contentY += scrollValue
                                }
                                else {
                                    //make sure not to scroll too far
                                    if (!_scrollview.flickableItem.atYBeginning)
                                    _scrollview.flickableItem.contentY -= scrollValue
                                }
                            }
                            onPressed: {
                                // forward mouse event
                                mouse.accepted = false
                            }
                            onReleased: {
                                // forward mouse event
                                mouse.accepted = false
                            }
                    }
                }
            }
        }
    }
}

使用onWheel - 事件将任何滚动转发到ScrollView。通过为您希望转发的任何鼠标事件设置mouse.accepted = false;,可以将其他鼠标事件(例如单击)转发给父级(在本例中为滑块)。

编辑:哦,我刚刚看到您不希望对滑块内容进行任何更改。您也可以尝试在ScrollView 上放置一个MouseArea 并进行相同的转发。

【讨论】:

  • 谢谢!我可以在 over Slider 上放置一些东西,但我不能为它编辑 Qt 的源代码。很快就会尝试一下,让你知道我的结果。
  • 使用相当复杂的事件处理程序添加更多对象只是为了禁用 deprecated 模块的 feature/bug,看起来不像 解决方案给我。这似乎相当hackish。完全重新实现Slider 可能会更好。有些人甚至会说,这样做总是比考虑使用 QtQuick.Control 更好;-)
【解决方案2】:

如果对您可行,最简单的方法可能是从 QtQuick.Controls 1.4 更改为新的 QtQuick.Controls 2.0,这可以被认为是 deprecated,未维护,或 low-performing

在此版本中,您的问题已得到解决。
为了满足您对QtQuick.Controls 1.4 的需求,我们将使用别名导入QtQuick.Controls 2.0

import QtQuick 2.7
import QtQuick.Controls 1.4
import QtQuick.Controls 2.0 as NewCtrl

Column {
    Slider {
        id: oldslider // old slider from QtQuick.Controls 1.4 with your issue
        width: 500
        height: 250
    }

    NewCtrl.Slider {
        id: newsli // new slider without your issue. Both side by side
        width: 500
        height: 30
        wheelEnabled: false // use this to enable or disable the wheel
    }
}

当然,您也可以为旧控件设置别名并使用新控件作为基本控件...或同时为两者设置别名。随你喜欢

【讨论】:

  • 你是对的,但是我的应用程序窗口需要 menuBar,由于某种原因在这个版本中被删除了
  • 那很糟糕。没有人应该阻止您使用 menuBar。幸运的是,您可以同时导入:import QtQuick.Controls 2.0import QtQuick.Controls 1.4 as OldCtrl 然后使用旧的 OldCtrl.MenuBar ;-)
  • 或者等待 Qt 5.8 并希望它在那里。
  • 在玩过Controls 2.0 之后,我意识到当你已经有基于Controls 1.x 的中大型应用程序时,切换到它并不容易。无论如何感谢您的回答,谢谢!
【解决方案3】:

来自here 的黑客为我做了这件事。

Slider {
    id: slider
    Component.onCompleted: {
        for (var i = 0; i < slider.children.length; ++i) {
            if (slider.children[i].hasOwnProperty("onVerticalWheelMoved") && slider.children[i].hasOwnProperty("onHorizontalWheelMoved")) {
                slider.children[i].destroy()
            }
        }
    }
}

这可能不适用于其他控件(例如 ComboBox)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多