Kivy+Python开发中无法获取自定义LongTouchButton按钮id求助
Kivy自定义按钮获取id的解决方案
错误原因说明
- Kivy 中
ids是父控件的属性,存储的是父控件下所有子控件的id映射,你在LongTouchButton实例内部调用self.ids,拿到的是按钮自身内部子控件的id集合,并不是你在KV文件中给按钮设置的bt1/bt2标识 - 你代码中两个按钮的
text属性均设置为"self.id",且你尝试访问的self.ids.bt1并不存在于按钮的内部id集合中,所以判断逻辑失效 self.ids是字典类型,直接和字符串"bt2"对比类型不匹配,永远返回False
最优解决方案:给按钮添加自定义标识属性
这是耦合度最低、实现最简单的方案,步骤如下:
1. 修改Python代码,给自定义按钮类添加标识属性
from kivymd.uix.behaviors import TouchBehavior from kivymd.uix.button import MDIconButton from kivy.lang import Builder from kivy.clock import Clock from kivy.core.window import Window from kivymd.app import MDApp class MainApp(MDApp): def __init__(self, **kwargs): super().__init__(**kwargs) self.kv =Builder.load_file('kv file') # 替换为你的kv文件实际路径 Window.maximize() # 窗口初始尺寸 def build(self): return self.kv class LongTouchButton(MDIconButton, TouchBehavior): # 自定义属性,用来存储按钮的唯一标识 btn_id = "" def __init__(self,**kwargs): super().__init__(**kwargs) self.duration_long_touch = 2 # 长按功能触发时长 def on_long_touch(self,*args): # 直接通过self.btn_id区分触发长按的按钮 print(f"长按触发,按钮id:{self.btn_id}") self.m = True self.while_long() def on_release(self, *args): self.m = False def while_long(self, *args): if self.m: print(f"LOOP! 来自按钮:{self.btn_id}") Clock.schedule_once(self.while_long, .5) def prints(self,*args): # 按自定义标识判断执行对应逻辑 if self.btn_id == "bt1": print("BUTTON 1 IS PRESSED") # 执行function1 elif self.btn_id == "bt2": print("BUTTON 2 IS PRESSED") # 执行function2 if __name__=='__main__': MainApp().run()
2. 修改KV文件,给每个按钮赋值自定义标识
FloatLayout: orientation: "vertical" MDToolbar: title: "ACESS TO ID WITH PROBLEM" text_color: app.theme_cls.primary_color md_bg_color: 0, 0.3, 0.6, 1 MDFloatLayout: LongTouchButton: id: bt1 btn_id: "bt1" # 和你要的标识保持一致即可 text: "bt1" user_font_size : 80 pos_hint: {"center_x": .3, "center_y": .5} on_press: self.prints() LongTouchButton: id: bt2 btn_id: "bt2" # 和你要的标识保持一致即可 text: "bt2" user_font_size : 80 pos_hint: {"center_x": .7, "center_y": .5} on_press: self.prints()
可选替代方案:通过父布局id对比
如果不想加自定义属性,也可以直接和父布局存储的控件实例对比,判断逻辑如下:
from kivymd.app import App def prints(self,*args): root = App.get_running_app().root if self == root.ids['bt1']: print("BUTTON 1 IS PRESSED") elif self == root.ids['bt2']: print("BUTTON 2 IS PRESSED")
这种方法不需要修改KV文件,但耦合度较高,父布局层级变更后需要同步修改代码。
内容的提问来源于stack exchange,提问作者Murobot
相关产品推荐
相关产品推荐

