Kivy 中滑块的干扰

Interference of Sliders in Kivy

我正在学习 Kivy,目前正在尝试理解 Slider class。我创建了两个滑块。滑块一应该只对 on_touch_move 做出反应,而滑块二应该对 on_touch_up 和 on_touch_down 做出反应。如果我实现这个,就像我在下面的例子中所做的那样,两个滑块都会干扰,即它们对所有三个事件调度程序做出反应。我试图理解为什么会这样以及如何解决这个问题,但我做不到。谢谢你帮我。

sliders.kv 文件:

#: kivy 1.9.0

SliderScreen:

<SliderScreen>:

    Slider:
        min: 0 
        max: 1
        value: 0.75
        step: 0.01
        on_touch_move: root.test_a()


    Slider:
        min: 0 
        max: 1
        value: 0.25
        step: 0.01
        on_touch_up: root.test_b()
        on_touch_down: root.test_c()

和main.py:

import kivy
kivy.require('1.9.0')

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.slider import Slider

class SliderScreen(BoxLayout):
    def test_a(self):
        print("test_a accessed")

    def test_b(self):
        print("test_b accessed")

    def test_c(self):
        print("test_c accessed")        

class SlidersApp(App):
    pass

if __name__ == '__main__':
    SlidersApp().run()  

on_touch_moveon_touch_upon_touch_down 事件由 SliderScreen class 捕获,然后传播到其所有小部件。根据 documentation:

By default, touch events are dispatched to all currently displayed widgets. This means widgets recieve the touch event whether it occurs within their physical area or not.

This can be counter intuitive if you have experience with other GUI toolkits. These typically divide the screen into geometric areas and only dispatch touch or mouse events to the widget if the coordinate lies within the widgets area.

This requirement becomes very restrictive when working with touch input. Swipes, pinches and long presses may well originate from outside of the widget that wants to know about them and react to them.

In order to provide the maximum flexibility, Kivy dispatches the events to all the widgets and lets them decide how to react to them. If you only want to respond to touch events inside the widget, you simply check:

def on_touch_down(self, touch):
    if self.collide_point(*touch.pos):
        # The touch has occurred inside the widgets area. Do stuff!
        pass

因此您应该在代码中使用:

Builder.load_string("""

<SliderScreen>:
    Slider:
        min: 0 
        max: 1
        value: 0.75
        step: 0.01
        on_touch_move: if self.collide_point(*args[1].pos): root.test_a()

    Slider:
        min: 0 
        max: 1
        value: 0.25
        step: 0.01
        on_touch_up: if self.collide_point(*args[1].pos): root.test_b()
        on_touch_down: if self.collide_point(*args[1].pos): root.test_c()
 """)

class SliderScreen(BoxLayout):
    def test_a(self):
        print("test_a accessed")

    def test_b(self):
        print("test_b accessed")

    def test_c(self):
        print("test_c accessed")