You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

实现Kivy ScrollView的SHIFT+鼠标滚轮水平滚动功能

解决方案:实现SHIFT+鼠标滚轮水平滚动的ScrollView

实现思路

由于Kivy的MotionEvent不携带修饰键信息,我们可以通过监听Window的鼠标事件捕获SHIFT键状态,然后在ScrollView的滚动处理逻辑中,根据该状态切换滚动方向,同时复用原生的滚动效果来保证平滑动画,兼容do_scroll_x、do_scroll_y、always_overscroll等属性。

完整代码实现

__version__ = '1.0.2'

from kivy.uix.scrollview import ScrollView
from kivy.base import runTouchApp
from kivy.lang import Builder
from kivy.properties import StringProperty, BooleanProperty
from kivy.core.window import Window

Builder.load_string('''
<ScrolllabelLabel>:
    do_scroll_x: True
    do_scroll_y: True
    always_overscroll: False
    effect_cls: "ScrollEffect"
    Label:
        text: root.text
        font_size: 18
        size_hint_y: None
        height: self.texture_size[1]
        size_hint_x: None
        width: self.texture_size[0]
''')


class ScrolllabelLabel(ScrollView):
    text = StringProperty('Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.\n' * 100)
    _shift_pressed = BooleanProperty(False)

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        # 绑定Window的鼠标事件跟踪SHIFT键状态
        Window.bind(on_mouse_down=self._on_window_mouse_down)
        Window.bind(on_mouse_up=self._on_window_mouse_up)

    def _on_window_mouse_down(self, window, pos, button, modifiers):
        self._shift_pressed = 'shift' in modifiers

    def _on_window_mouse_up(self, window, pos, button, modifiers):
        # 释放鼠标时仍检查SHIFT键状态
        self._shift_pressed = 'shift' in modifiers

    def _on_mouse_scroll(self, touch):
        # SHIFT按下且允许水平滚动时,切换滚动轴为x
        if self._shift_pressed and self.do_scroll_x:
            touch.ud['scroll_x'] = touch.ud.get('scroll_y', 0)
            touch.ud['scroll_y'] = 0
            return super()._on_mouse_scroll(touch)
        # 否则按原生逻辑处理垂直滚动
        return super()._on_mouse_scroll(touch)


runTouchApp(ScrolllabelLabel())

代码说明

  1. SHIFT键状态跟踪:通过绑定Window的鼠标按下/抬起事件,实时更新_shift_pressed属性,准确获取SHIFT键的激活状态
  2. 滚动方向切换:重写_on_mouse_scroll方法,当SHIFT激活时,将触摸事件的滚动轴从y轴切换为x轴,再调用原生滚动逻辑,完美复用原生平滑动画
  3. 配置兼容性:完全遵守ScrollView的do_scroll、always_overscroll等属性配置,不破坏原有垂直滚动功能

内容的提问来源于stack exchange,提问作者AliSot 2000

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 06:40:18