如何暂停Python脚本直至Tkinter Toplevel按钮被点击并返回选择?
实现Tkinter模态阻塞弹窗(类似input函数)
要实现和input()一样的阻塞效果,同时锁定其他Tkinter窗口,不用额外的mouse模块,Tkinter本身就提供了对应的方法:
核心修改点
- 模态锁定:给Toplevel窗口调用
grab_set(),这样用户无法操作其他Tkinter窗口,只能和当前弹窗交互 - 阻塞等待:调用
root.wait_window(),让程序暂停在这一行,直到弹窗被销毁后才继续执行 - 修正变量赋值:不用
exec这种不合理的方式,用nonlocal关键字在按钮回调里修改函数内的chosen变量
修改后的完整代码
"""this is a script to alert a message in a tkinter toplevel window.""" from tkinter import Toplevel, Text, Button root = None def alert(msg, choice=False, button_a_msg="Ok", button_b_msg="cancel"): try: global root if root is not None: root.destroy() # 销毁已存在的弹窗,避免重复 chosen = None def set_choice(val): nonlocal chosen chosen = val root.destroy() # 选择后销毁窗口,触发wait_window结束 root = Toplevel() root.geometry("300x100") # 调整尺寸让内容显示更合理 text = Text(root) text.insert("1.0", msg) text.config(state="disabled") text.pack(expand=True, fill="both", padx=10, pady=10) if choice: button_a = Button(root, text=button_a_msg, command=lambda: set_choice('a')) button_a.pack(side="left", expand=True, padx=10, pady=5) button_b = Button(root, text=button_b_msg, command=lambda: set_choice('b')) button_b.pack(side="right", expand=True, padx=10, pady=5) else: # 没有choice时添加默认的Ok按钮 button_ok = Button(root, text="Ok", command=lambda: set_choice('ok')) button_ok.pack(padx=10, pady=5) root.grab_set() # 锁定其他窗口,只能操作当前弹窗 root.wait_window() # 阻塞程序,直到窗口被销毁 return chosen except Exception as e: print(f"错误: {e}") return None
关键代码解释
grab_set():将当前Toplevel设置为模态窗口,所有其他Tkinter窗口的事件都会被拦截,用户必须先处理这个弹窗才能操作其他窗口wait_window():让程序暂停执行,直到这个Toplevel窗口被销毁(比如点击按钮后调用root.destroy()),之后才会继续执行后续代码并返回chosen的值set_choice函数:用nonlocal关键字访问外部函数的chosen变量,避免了exec的不合理用法,同时在设置选择后销毁窗口,触发等待结束
测试这个函数时,调用result = alert("请选择操作", choice=True),程序会暂停,直到用户点击按钮,result会得到对应的选择值('a'/'b'/'ok'),期间其他Tkinter窗口完全无法操作。
内容的提问来源于stack exchange,提问作者Jasper Bart
相关产品推荐
相关产品推荐

