如何动态为Tkinter根窗口绑定事件 resize事件触发异常如何解决
问题根因
- Style实例未被持有:你在
MainWindow.__init__中直接创建Style(self)但没有赋值给实例变量,该实例创建后会立刻被Python垃圾回收,绑定的__resize回调方法随实例销毁,自然无法正常触发,这是事件仅触发一次、甚至不触发的核心原因。 - Frame控件创建错误:
frame = ttk.Frame(self).grid(column=0, row=0)的写法错误,grid()方法返回值为None,因此frame变量实际为空,后续Label的父控件逻辑异常,也会干扰布局和事件链路。 - 可选优化:根窗口绑定的
<Configure>事件会被子控件的尺寸变化触发,建议加一层判断,仅当事件触发源为根窗口时才执行逻辑,避免取到错误的控件宽度。
修复代码
style.py
import tkinter.ttk as ttk class Style(ttk.Style): _window = None def __init__(self, window): super().__init__(window) self._window = window self.configure("USERINFO.TLabel", font=('script', 12)) self._window.bind("<Configure>", self.__resize) def __resize(self, event): # 仅处理根窗口的尺寸变化事件 if event.widget != self._window: return if event.width > 600: self.configure("USERINFO.TLabel", font=('Helvetica', 5)) else: self.configure("USERINFO.TLabel", font=('script', 12))
guy.py
import tkinter import tkinter.ttk as ttk from style import Style class MainWindow(tkinter.Tk): def __init__(self): super().__init__() # 持有Style实例,避免被回收 self.style = Style(self) self._clientarea() def _clientarea(self): # 分开写控件创建和布局,避免frame为None frame = ttk.Frame(self) frame.grid(column=0, row=0) ttk.Label(frame, text="Username: ", style="USERINFO.TLabel").grid(column=0, row=0) if __name__ == "__main__": root = MainWindow() root.mainloop()
验证效果
修改后拉伸窗口,宽度大于600时标签字体会自动切换为5号,宽度缩小到600以内时会自动切回12号,每次窗口尺寸变化都会触发回调逻辑。
内容的提问来源于stack exchange,提问作者david stephen
相关产品推荐
相关产品推荐

