Kivy自定义TextInput子类调用select_all全选所有实例问题咨询
第一次实现点击任意文本框全选所有实例的原因
Kivy的触摸事件采用冒泡分发机制:所有处于显示树中的控件都会依次收到触摸事件,直到有控件的on_touch_down方法返回True表示已消费该事件,才会停止分发。
你第一次的on_touch_down实现没有做事件归属判断:只要该方法被触发(不管触摸点是否在当前控件范围内),都会执行全选逻辑。点击屏幕时所有TextEntry实例都会收到触摸事件,自然所有实例都会执行全选。
修复方案只需判断父类是否已经消费了该事件(即触摸点落在当前控件上)再执行全选即可:
class TextEntry(TextInput): def on_touch_down(self, touch): if super().on_touch_down(touch): Clock.schedule_once(lambda dt: self.select_all()) return True return False
第二次实现root与self表现不同的原因
你第二次的KV写法相当于在TextEntry(本身是TextInput子类)内部嵌套了一个子TextInput控件,on_touch_down回调是绑定在这个子控件上的:
- 使用
root.select_all()时:KV规则中的root指向当前规则的根控件,也就是你点击位置对应的外层TextEntry实例,仅会触发当前被点击的TextEntry执行全选,因此表现正常。 - 使用
self.select_all()时:这里的self指向子TextInput本身,由于你没有在回调中消费事件,触摸事件会继续分发给其他所有控件的子TextInput,所有子控件的回调都会被触发,因此出现全选所有实例的问题。
额外提示:你的第二次实现存在不必要的嵌套,
TextEntry本身已经是TextInput子类,无需再嵌套子TextInput,直接给TextEntry绑定事件即可:<TextEntry>: on_touch_down: if super().on_touch_down(args[1]): Clock.schedule_once(lambda dt: self.select_all())
内容的提问来源于stack exchange,提问作者Hannes Ziegler
相关产品推荐
相关产品推荐

