为 QML Slider 禁用鼠标滚轮
Disable mouse wheel for QML Slider
我希望能够在不更改 Slider
s 的情况下使用鼠标滚轮(或触摸板上的两个手指)滚动 Flickable
。
示例代码和结果应用:
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,但是没有成功。
EDIT:这仅与 Controls 1.x
有关,因为从 2.0 版本开始控件似乎没有此问题。
您可以在滑块上放置 MouseArea
s 以窃取鼠标滚轮事件。
像这样:
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
并进行相同的转发。
如果对您可行的话,最简单的方法可能是从 QtQuick.Controls 1.4
更改为新的 QtQuick.Controls 2.0
,后者可以被视为 deprecated, not maintained, or 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
}
}
当然,您也可以为旧控件设置别名,将新控件用作基本控件...或者同时为两者设置别名。随心所欲
here 的 Hack 帮我做了。
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)。
我希望能够在不更改 Slider
s 的情况下使用鼠标滚轮(或触摸板上的两个手指)滚动 Flickable
。
示例代码和结果应用:
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,但是没有成功。
EDIT:这仅与 Controls 1.x
有关,因为从 2.0 版本开始控件似乎没有此问题。
您可以在滑块上放置 MouseArea
s 以窃取鼠标滚轮事件。
像这样:
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
并进行相同的转发。
如果对您可行的话,最简单的方法可能是从 QtQuick.Controls 1.4
更改为新的 QtQuick.Controls 2.0
在此版本中,您的问题已得到解决。
为了满足您对 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
}
}
当然,您也可以为旧控件设置别名,将新控件用作基本控件...或者同时为两者设置别名。随心所欲
here 的 Hack 帮我做了。
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)。