为什么 KivyMD on_touch_down 事件会触发多个项目?
Why is KivyMD on_touch_down event triggering multiple items?
我的 KivyMD 应用程序中有一个屏幕,其中包含项目列表。我的 objective 是根据单击的项目导航到不同的屏幕。我注意到无论我选择哪个项目,下一个屏幕都与单击的项目相关或不相关。好像是随机的。
下面是一个可重现的例子。为了简化,我删除了大部分项目并用简单的打印功能替换了导航。
当单击一个项目或“取消”按钮时,会打印多个文本,就好像我单击了屏幕上的多个元素(例如,单击项目 1 会导致“项目 3 项目 2 项目 1 “正在打印)我怀疑这就是导航不一致的原因
我觉得这很混乱。有人可以向我解释这里发生了什么吗?谢谢:)
from kivy.lang import Builder
from kivymd.app import MDApp
KV = '''
MDScreen:
name: "screen1"
MDBoxLayout:
orientation: "vertical"
MDToolbar:
id : tb_screen1
title: "Select Item"
on_touch_down:
app.p(self.title)
ScrollView:
MDList:
OneLineListItem:
text: "item1"
on_touch_down:
app.p(self.text)
OneLineListItem:
text: "item2"
on_touch_down:
app.p(self.text)
OneLineListItem:
text: "item3"
on_touch_down:
app.p(self.text)
MDBoxLayout:
MDFloatLayout:
MDRectangleFlatIconButton:
text: "Cancel"
on_press:
app.p(self.text)
'''
class MainApp(MDApp):
def build(self):
return Builder.load_string(KV)
def p(self,text):
print(text)
MainApp().run()
这是 touch
事件处理的设计行为。 touch
事件被传递给所有小部件,每个小部件负责确定它是否应该响应 touch
。扩展 ButtonBehavior
的小部件(如 OneLineListItem
和 MDRectangleFlatIconButton
)在 on_press
和 on_release
行为中内置了该测试,因此您可以只使用 on_press
或 on_release
(而不是 on_touch_down
)。
MDToolbar
没有 ButtonBehavior
,因此您必须将该测试添加到 on_touch_down
。你可以这样做:
MDToolbar:
id : tb_screen1
title: "Select Item"
on_touch_down:
app.p(self.title) if self.collide_point(*args[1].pos) else False
以上 kv
代码仅在触摸点位于 MDToolbar
范围内时调用 app.p(self.title)
。上面的args
是kivy中的关键字(参见keywords)。 args[1]
就是touch
,pos
就是那个touch
的位置。前面的 *
将 pos
扩展为其 x
、y
组件(如 collide_point()
方法所期望的那样)。
我的 KivyMD 应用程序中有一个屏幕,其中包含项目列表。我的 objective 是根据单击的项目导航到不同的屏幕。我注意到无论我选择哪个项目,下一个屏幕都与单击的项目相关或不相关。好像是随机的。
下面是一个可重现的例子。为了简化,我删除了大部分项目并用简单的打印功能替换了导航。
当单击一个项目或“取消”按钮时,会打印多个文本,就好像我单击了屏幕上的多个元素(例如,单击项目 1 会导致“项目 3 项目 2 项目 1 “正在打印)我怀疑这就是导航不一致的原因
我觉得这很混乱。有人可以向我解释这里发生了什么吗?谢谢:)
from kivy.lang import Builder
from kivymd.app import MDApp
KV = '''
MDScreen:
name: "screen1"
MDBoxLayout:
orientation: "vertical"
MDToolbar:
id : tb_screen1
title: "Select Item"
on_touch_down:
app.p(self.title)
ScrollView:
MDList:
OneLineListItem:
text: "item1"
on_touch_down:
app.p(self.text)
OneLineListItem:
text: "item2"
on_touch_down:
app.p(self.text)
OneLineListItem:
text: "item3"
on_touch_down:
app.p(self.text)
MDBoxLayout:
MDFloatLayout:
MDRectangleFlatIconButton:
text: "Cancel"
on_press:
app.p(self.text)
'''
class MainApp(MDApp):
def build(self):
return Builder.load_string(KV)
def p(self,text):
print(text)
MainApp().run()
这是 touch
事件处理的设计行为。 touch
事件被传递给所有小部件,每个小部件负责确定它是否应该响应 touch
。扩展 ButtonBehavior
的小部件(如 OneLineListItem
和 MDRectangleFlatIconButton
)在 on_press
和 on_release
行为中内置了该测试,因此您可以只使用 on_press
或 on_release
(而不是 on_touch_down
)。
MDToolbar
没有 ButtonBehavior
,因此您必须将该测试添加到 on_touch_down
。你可以这样做:
MDToolbar:
id : tb_screen1
title: "Select Item"
on_touch_down:
app.p(self.title) if self.collide_point(*args[1].pos) else False
以上 kv
代码仅在触摸点位于 MDToolbar
范围内时调用 app.p(self.title)
。上面的args
是kivy中的关键字(参见keywords)。 args[1]
就是touch
,pos
就是那个touch
的位置。前面的 *
将 pos
扩展为其 x
、y
组件(如 collide_point()
方法所期望的那样)。