Kivy中调度创建Widget报错:AttributeError: 'float'对象无ids属性
问题原因
你调用Clock.schedule_once时直接传了类方法MyLayout.add_label,而不是当前实例的方法。Clock执行回调时,会把延迟的时间差(一个float类型的dt值)作为第一个参数传给add_label,这就导致add_label里的self被替换成了这个float值,自然找不到ids属性。直接调用self.add_label()时,self是正确的实例,所以能正常运行。
解决方案
有两种简单的修复方式:
方式一:用lambda绑定实例方法
修改schedule_widget方法,通过lambda忽略dt参数并调用实例的add_label:
def schedule_widget(self): Clock.schedule_once(lambda dt: self.add_label(), 5)
方式二:让add_label接受dt参数
调整add_label方法,让它接收Clock传递的dt参数(即使你不用这个参数),然后直接传递实例方法给schedule_once:
def schedule_widget(self): Clock.schedule_once(self.add_label, 5) def add_label(self, dt): self.ids.id.add_widget(Label(text=f'Hello World'))
额外建议
你的kv文件里给BoxLayout的id取名为id,这是Python的关键字,虽然当前不报错,但可能引发潜在问题,建议改成更清晰的名字,比如main_box,对应的kv和代码里的self.ids.id也要改成self.ids.main_box。
修改后的完整代码示例(用方式二):
main.py
from kivy.app import App from kivy.uix.widget import Widget from kivy.uix.label import Label from kivy.lang import Builder from kivy.clock import Clock Builder.load_file('test.kv') class MyLayout(Widget): def schedule_widget(self): Clock.schedule_once(self.add_label, 5) def add_label(self, dt): self.ids.main_box.add_widget(Label(text=f'Hello World')) class MyApp(App): def build(self): return MyLayout() if __name__ == '__main__': MyApp().run()
test.kv
<MyLayout> BoxLayout: orientation: 'horizontal' size: root.width, root.height id: main_box Button: text: 'Add A Label in 5 seconds' on_release: app.root.schedule_widget()
内容的提问来源于stack exchange,提问作者TechnicalVoid
相关产品推荐
相关产品推荐

