忽略ScrollView中的区域以滚动交互

时间:2016-02-29 21:46:41

标签: python scrollview kivy

假设我的这个UI改编自ScrollView示例:

from kivy.app import App
from kivy.uix.slider import Slider
from kivy.uix.label import Label
from kivy.uix.scrollview import ScrollView
from kivy.uix.gridlayout import GridLayout
from kivy.uix.boxlayout import BoxLayout

class ScrollViewApp(App):
    def build(self):
        layout = GridLayout(cols=1, padding=10, spacing=10,
                size_hint=(None, None), width=500)
        layout.bind(minimum_height=layout.setter('height'))
        for i in range(15):
            blt = BoxLayout(size_hint=(None, None), size=(480, 40))
            blt.add_widget(Label(text="Slider %d" % i))
            btn = Slider(value=i, min=0, max=42, size=(400, 40),
                         size_hint=(None, None))
            blt.add_widget(btn)
            layout.add_widget(blt)
        scroll = ScrollView(size_hint=(None, None), size=(500, 320),
                pos_hint={'center_x': .5, 'center_y': .5}, do_scroll_x=False)
        scroll.add_widget(layout)
        return scroll

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

由于scroll_timeout,与Slider的互动会延迟。是否可以在ScrollView中定义touch事件刚刚传递给孩子的区域(没有启动滚动)?

2 个答案:

答案 0 :(得分:2)

查看Widget touch event bubbling

我从来没有做过与你相同的事情,但也许你可以创建一个继承ScrollView并覆盖on_touch_down事件的自定义类,你可以:

  1. 禁用滚动
  2. 致电super.on_touch_down
  3. 启用滚动。
  4. 另一种方法可能是创建一个自定义窗口小部件,该窗口小部件继承用户单击的Slider类。然后使用on_touch_down重载return True方法。 Documentation says

      

    为了阻止此事件冒泡,其中一个方法必须返回True

    ScrollView也会触发on_scroll_start事件,所以也许你可以在那里做类似的事情。

答案 1 :(得分:2)

我想出了ScrollView的{​​{1}}的简单覆盖,到目前为止似乎满足了我的需求。我们的想法是测试触摸事件是否属于“禁区”(在下面的示例中,仅检查x维度,但将其扩展到任意矩形区域是微不足道的)。如果它确实属于该禁区,on_touch_down事件将被发送给on_touch_down的孩子。如果孩子捕获它,则吞下该事件。在所有其他情况下,将调用ScrollView,即启动正常滚动行为。如果触摸没有落在super.on_touch_down上(在问题的示例中),那么仍然可以滚动。

Slider