Kivy开发:动态添加到屏幕的Widget无法删除问题求助
解决方法
你当前的代码只实现了匹配内容时新增下拉选项的逻辑,缺少旧控件的清理步骤,只要在每次生成新的下拉选项前,先删除此前动态添加的所有按钮即可,具体修改如下:
- 给动态生成的按钮添加专属标识,用于后续清理时快速识别;
- 每次触发
create_dropdown方法时先清理所有历史动态按钮,再根据当前输入内容决定是否生成新的选项。
修改后完整代码
import kivy from kivy.app import App from kivy.lang import Builder from kivy.uix.textinput import TextInput kivy.require('1.9.0') from kivy.uix.button import Button from kivy.base import runTouchApp from kivy.uix.screenmanager import ScreenManager,Screen class ScreenOne(Screen): def change_text(self,root,val): pass def create_dropdown(self,root,value): # 先清理所有之前动态添加的按钮 for widget in root.ids.screen1.children[:]: # 只删除带有动态标识的控件 if hasattr(widget, 'is_dynamic_option'): root.ids.screen1.remove_widget(widget) if value == "": return lang = ["aa","aaa", "bsa","cds","dds", "ddyus"] result = list(filter(lambda x: x.startswith(value), lang)) for i in range(len(result)): btn = Button() btn.id = 'textinput'+ str(i) btn.text = result[i] btn.size_hint= (.3, .06) btn.font_size= '14sp' btn.pos_hint= {'center_x': 0.5, 'center_y': 0.8-(i+1)/10, } # 添加专属标识,用于后续清理 btn.is_dynamic_option = True root.ids.screen1.add_widget(btn) sm = Builder.load_string(""" ScreenManager: ScreenOne: id: screen1 name: "screen_one" TextInput: id: input1 hint_text:'Select input Language' size_hint: (.3,.06) font_size: '14sp' pos_hint:{'center_x':0.5,'center_y':0.8,} on_text: root.ids.screen1.create_dropdown(root,input1.text) """) class demo(App): def build(self): return sm app=demo() runTouchApp(sm)
关键逻辑说明
- 遍历子控件时使用
root.ids.screen1.children[:]是为了生成子控件列表的副本,避免遍历过程中修改原列表导致的遍历异常 - 自定义
is_dynamic_option属性可以避免误删输入框等固定控件 - 无论输入内容是否为空都先执行清理逻辑,既解决了清空输入无反应的问题,也避免了输入内容变化时旧选项残留重复的问题
内容的提问来源于stack exchange,提问作者bidyut nanda
相关产品推荐
相关产品推荐

