tkinter simpledialog提交后焦点跳转至父窗口问题排查
问题原因
这个现象是simpledialog本身的机制导致的,和你的类编写逻辑无关。
tkinter内置的所有模态对话框(包括simpledialog、messagebox、filedialog等)关闭时,都会默认将焦点返还给创建对话框时绑定的父窗口。你调用simpledialog.askstring时,新建的window2正处于withdraw()隐藏状态,simpledialog会自动把当前处于激活状态的window1识别为父窗口,因此对话框销毁后自动把焦点归还到window1,后续调用window2的deiconify()也不会覆盖这个已执行的焦点调度逻辑,直接调用focus_set()也会被之前的焦点归还事件覆盖,所以无法生效。
解决方法
只需要在调用askstring时,显式指定parent参数为当前window2的根窗口即可,对话框关闭后会自动将焦点返还到你指定的父窗口:
class window2: def __init__(self,root): self.root = root self.root.withdraw() # 新增parent参数,指定父窗口为window2本身 simpledialog.askstring("askstring","askstring", parent=self.root) self.root.deiconify()
如果部分场景下还是存在焦点漂移问题,可以加一行延迟调用focus_force()强制抢占焦点,适配tkinter的事件队列调度逻辑:
class window2: def __init__(self,root): self.root = root self.root.withdraw() simpledialog.askstring("askstring","askstring", parent=self.root) self.root.deiconify() # 延迟50毫秒强制获取焦点,避免被之前的焦点事件覆盖 self.root.after(50, self.root.focus_force)
修改后运行即可实现关闭对话框后window2正常获得焦点的效果。
内容的提问来源于stack exchange,提问作者Nikolas Anctil
相关产品推荐
相关产品推荐

