【问题标题】:Why is KivyMD on_touch_down event triggering multiple items?为什么 KivyMD on_touch_down 事件会触发多个项目?
【发布时间】:2021-12-31 11:04:56
【问题描述】:

我的 KivyMD 应用程序中有一个屏幕,其中包含项目列表。我的目标是根据单击的项目导航到不同的屏幕。我注意到无论我选择哪个项目,下一个屏幕都会或不会与单击的项目相关。这似乎是随机的。

以下是一个可重现的示例。为简化起见,我删除了大部分项目并将导航替换为简单的打印功能。

当单击一个项目或“取消”按钮时,会打印多个文本,就好像我单击了屏幕的多个元素一样(例如,单击 item1 会导致打印“item3 item2 item1”)我怀疑这就是导航不一致的原因

我觉得这很混乱。有人可以解释一下这里发生了什么吗?谢谢:)

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()

【问题讨论】:

    标签: python kivy kivymd


    【解决方案1】:

    这是touch 事件处理的设计行为。 touch 事件被传递给所有小部件,每个小部件负责确定它是否应该响应 touch。扩展ButtonBehavior 的小部件(如OneLineListItemMDRectangleFlatIconButton)在on_presson_release 行为中内置了该测试,因此您可以对这些小部件使用on_presson_release(而不是@ 987654332@).

    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]touchpostouch 的位置。前面的*pos 扩展为其xy 组件(正如collide_point() 方法所期望的那样)。

    【讨论】:

    • 非常感谢@John Anderson 这个写得很好的答案。我能够解决问题并了解发生了什么。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多