tkinter控件单行调用pack()被回收且返回NoneType的原因
产生原因
这个现象是Tkinter的方法设计+Python赋值执行逻辑共同导致的:
- Tkinter所有内置布局方法,包括
pack()、grid()、place(),设计上就没有返回值,调用后默认返回None。 - 链式写法
photo_label = Label(root, image=photos[0]).pack()的执行顺序是:- 先在内存中创建
Label控件实例 - 立刻调用这个实例的
pack()方法完成布局 - 把
pack()方法的返回值(也就是None)赋值给photo_label变量
这种写法下photo_label从一开始接收到的就不是Label控件对象,打印类型自然会输出NoneType。同时因为没有任何变量持有刚创建的Label实例的引用,Python垃圾回收机制会自动回收这个无引用的对象,后续经常会出现控件不显示、图片丢失之类的异常。
- 先在内存中创建
- 拆分两行的写法中,第一行
photo_label = Label(root, image=photos[0])是直接把Label实例本身赋值给变量,持有了控件的有效引用;第二行单独调用photo_label.pack()时,方法返回的None没有被变量接收,不会覆盖photo_label存储的控件实例,所以变量类型是正常的tkinter Label对象,控件也不会被意外回收。
开发提示:所有Tkinter开发场景下都不要把控件实例化和布局方法做链式调用,必须拆分为两行书写,否则既无法通过变量操作控件(比如修改文本、绑定事件、销毁控件),还会出现很多难以排查的界面异常。
内容的提问来源于stack exchange,提问作者Muhammed Ali Baturhan Aktekin
相关产品推荐
相关产品推荐

