![](/img/trans.png)
[英]Kivy Label: on_touch_down event is triggered everywhere in the screen
[英]Creating kivy behavior that dispatches event bubbling same way as on_touch_down
讓我們從基本示例開始:
class OuterWidget(Widget):
def on_touch_down(self, touch):
if self.collide_point(*touch.pos):
print('on_touch_down', self)
return True # doesn't dispatch to InnerWidget
return super().on_touch_down(touch)
class InnerWidget(Widget):
def on_touch_down(self, touch):
if self.collide_point(*touch.pos):
print('on_touch_down', self)
return super().on_touch_down(touch)
事件首先分派到OuterWidget
,如果它調用super().on_touch_down(touch)
事件分派到子小部件,否則接下來不會分派事件。 這很清楚。
我想創建一些與on_touch_down
發生的行為,並以相同的方式行事。 咱們試試吧:
class TestBehavior(Widget):
def __init__(self, **kwargs):
self.register_event_type('on_test_event')
super().__init__(**kwargs)
def on_test_event(self, touch):
pass
def on_touch_down(self, touch):
self.dispatch('on_test_event', touch) # Some event that happens with on_touch_down
return super().on_touch_down(touch)
class OuterWidget(TestBehavior, Widget):
def on_test_event(self, touch):
if self.collide_point(*touch.pos):
print('on_test_event', self)
return True # doesn't affect anything, both widgets would recieve on_test_event
return super().on_test_event(touch)
class InnerWidget(TestBehavior, Widget):
def on_test_event(self, touch):
if self.collide_point(*touch.pos):
print('on_test_event', self)
return True
return super().on_test_event(touch)
on_test_event
冒泡的工作方式與on_touch_down
。 無論OuterWidget
返回什么,事件都會被分派給InnerWidget
。 這是因為兩個小部件都會收到觸發on_test_event
on_touch_down
事件。
看起來如果我使用on_touch_down
來調度某個行為的事件,這個事件將始終被調度給所有孩子,無論他們返回什么。 但是如果某個小部件沒有調用super().on_test_event(touch)
我不想接下來調度on_test_event
。
我該怎么做? 有任何想法嗎?
Widget 類像這樣處理其所有子級的事件:
(復制自widget.py)
def on_touch_down(self, touch):
'''Receive a touch down event.
:Parameters:
`touch`: :class:`~kivy.input.motionevent.MotionEvent` class
Touch received. The touch is in parent coordinates. See
:mod:`~kivy.uix.relativelayout` for a discussion on
coordinate systems.
:Returns: bool
If True, the dispatching of the touch event will stop.
If False, the event will continue to be dispatched to the rest
of the widget tree.
'''
if self.disabled and self.collide_point(*touch.pos):
return True
for child in self.children[:]:
if child.dispatch('on_touch_down', touch):
return True
正如您所看到的,它遍歷其子進程並分派事件,直到返回True為止。
要創建類似的行為,您可以創建自己的混合類並使所有類都繼承自它或 **monkey patch Widget **
恕我直言,這會有點亂,我要做的是創建一個函數:
def fire_my_event(widget):
if hasattr(widget, 'on_test_event'):
if widget.on_test_event():
return True
for c in widget.children[:]:
if fire_my_event(c):
return True
#in your code somewhere
class SomeWidget(Image): #or anything else ...
def on_touch_down(self, touch):
fire_my_event(self)
玩得開心!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.