如何重写Tkinter Simpledialog中Cancel按钮的命令以跳出循环?
实现方案
要修改simpledialog.askinteger的Cancel按钮行为是可行的,核心思路是继承simpledialog.SimpleDialog类,重写按钮的创建逻辑,自定义Cancel按钮的触发命令。以下是具体步骤和代码示例:
1. 自定义对话框类
创建一个继承自simpledialog.SimpleDialog的子类,重写buttonbox方法(该方法负责创建对话框的按钮),同时添加一个属性标记用户是否点击了Cancel:
from tkinter import simpledialog from tkinter import messagebox import tkinter as tk class CustomIntegerDialog(simpledialog.SimpleDialog): def __init__(self, parent, title, prompt): self.user_canceled = False # 标记是否点击Cancel super().__init__(parent, title, prompt) def buttonbox(self): # 重写按钮创建逻辑 box = tk.Frame(self) # 创建OK按钮,保留原行为 ok_button = tk.Button(box, text="OK", width=10, command=self.ok, default=tk.ACTIVE) ok_button.pack(side=tk.LEFT, padx=5, pady=5) # 创建Cancel按钮,自定义命令 cancel_button = tk.Button(box, text="Cancel", width=10, command=self.custom_cancel) cancel_button.pack(side=tk.RIGHT, padx=5, pady=5) self.bind("<Return>", self.ok) self.bind("<Escape>", self.custom_cancel) box.pack() def custom_cancel(self): # 自定义Cancel行为:标记取消状态,再关闭对话框 self.user_canceled = True self.cancel()
2. 替换原对话框调用
将原来的simpledialog.askinteger替换为自定义对话框的实例化调用,并在每次调用后检查取消标记,决定是否跳出while循环:
root = tk.Tk() root.withdraw() # 隐藏主窗口,只显示对话框 prioritychoice = True while prioritychoice == True: # 实例化自定义对话框 dialog = CustomIntegerDialog(root, 'Priority Level', 'Which priority level would you like to view?') P1Cont = dialog.result # 获取用户输入的整数 # 检查是否点击了Cancel,若是则跳出循环 if dialog.user_canceled: break # 这里写显示对应优先级DataFrame的代码 print(f"用户选择的优先级:{P1Cont}") prioritychoice = messagebox.askyesno('Continue', 'Would you like to see information for a different priority level?')
关键说明
CustomIntegerDialog类通过重写buttonbox方法,替换了原Cancel按钮的命令为custom_cancel,该方法会先设置user_canceled为True,再调用原cancel()方法关闭对话框。- 调用自定义对话框后,通过
dialog.user_canceled判断用户是否点击了Cancel,若是则执行break跳出while循环。 root.withdraw()用于隐藏Tkinter的主窗口,避免额外窗口干扰。
内容的提问来源于stack exchange,提问作者imperialjasper
相关产品推荐
相关产品推荐

