如何获取Tkinter按钮绑定函数的返回值?
Tkinter登录验证结果存储解决方案
Tkinter按钮的command回调函数是异步触发的,无法直接捕获其返回值,要保存验证结果可以采用以下几种方式:
方法1:类封装(推荐)
把UI逻辑和状态封装到类里,用实例属性存储验证结果,代码结构更清晰、易维护。
import tkinter as tk from tkinter import Label, Button, Entry class LoginApp: def __init__(self, window, details): self.window = window self.background_colour = "#f0f0f0" self.text_colour = "#333333" self.width = window.winfo_screenwidth() self.height = window.winfo_screenheight() self.details = details self.authenticated_result = False # 存储验证结果的属性 # 创建UI元素 self.entries = self.create_entries() self.labels = self.create_labels() self.create_buttons() # 初始化提示标签 self.wrong_label = Label(window, text='Incorrect', bg=self.background_colour, fg=self.text_colour) self.correct_label = Label(window, text='Authenticated', bg=self.background_colour, fg=self.text_colour) def get_entry_values(self): username = self.entries['username'].get() password = self.entries['password'].get() return username, password def create_entries(self): entries = {} entries['username'] = Entry(self.window) entries['username'].place(x=self.width/10*4.8, y=self.height/10*2.5) entries['password'] = Entry(self.window, show='*') entries['password'].place(x=self.width/10*4.8, y=self.height/10*3) return entries def create_labels(self): labels = {} labels['user_lbl'] = Label(self.window, text='用户名:', bg=self.background_colour, fg=self.text_colour) labels['user_lbl'].place(x=self.width/10*3.8, y=self.height/10*2.5) labels['pwd_lbl'] = Label(self.window, text='密码:', bg=self.background_colour, fg=self.text_colour) labels['pwd_lbl'].place(x=self.width/10*3.8, y=self.height/10*3) return labels def authenticate(self): username, password = self.get_entry_values() self.authenticated_result = self.details.get(username) == password print("Authenticated" if self.authenticated_result else "Incorrect") label_pos = [self.width / 10 * 4.8, self.height / 10 * 3.5] if self.authenticated_result: self.wrong_label.destroy() self.correct_label.place(x=label_pos[0], y=label_pos[1]) else: self.correct_label.destroy() self.wrong_label.place(x=label_pos[0], y=label_pos[1]) # 后续可直接用self.authenticated_result做其他操作,比如页面跳转 def create_buttons(self): submit_btn = Button(self.window, text='Submit', command=self.authenticate) submit_btn.place(x=self.width / 10 * 7.3, y=self.height / 10 * 4.5) def main(details): window = tk.Tk() app = LoginApp(window, details) window.mainloop() # 事件循环结束后可获取结果 print("最终验证结果:", app.authenticated_result) # 测试用用户数据 test_details = {"admin": "123456", "user": "password"} main(test_details)
方法2:可变对象存储
用列表这类可变对象作为结果容器,函数内部修改容器内容,外部就能访问到最新值,适合小型脚本场景。
import tkinter as tk from tkinter import Label, Button, Entry width = tk.Tk().winfo_screenwidth() height = tk.Tk().winfo_screenheight() background_colour = "#f0f0f0" text_colour = "#333333" window = tk.Tk() def get_entry_values(entries): username = entries['username'].get() password = entries['password'].get() return username, password def authenticate(entries, details, result_store): username, password = get_entry_values(entries) authenticated = details.get(username) == password result_store[0] = authenticated # 结果存入列表 print("Authenticated" if authenticated else "Incorrect") label_pos = [width / 10 * 4.8, height / 10 * 3.5] wrong = Label(window, text='Incorrect', bg=background_colour, fg=text_colour) correct = Label(window, text='Authenticated', bg=background_colour, fg=text_colour) if authenticated: wrong.destroy() correct.place(x=label_pos[0], y=label_pos[1]) else: correct.destroy() wrong.place(x=label_pos[0], y=label_pos[1]) def insert_btn_commands(entries, details, result_store): all_btn = [{'text': 'Submit', 'pos': [width / 10 * 7.3, height / 10 * 4.5], 'command': lambda: authenticate(entries, details, result_store)}] return all_btn def create_buttons(all_btn): buttons = {} for i in range(len(all_btn)): buttons[f'button{i}'] = Button(window, text=all_btn[i]['text'], command=all_btn[i]['command']) buttons[f'button{i}'].place(x=all_btn[i]['pos'][0], y=all_btn[i]['pos'][1]) return buttons def create_entries(all_ents): entries = {} entries['username'] = Entry(window) entries['username'].place(x=width/10*4.8, y=height/10*2.5) entries['password'] = Entry(window, show='*') entries['password'].place(x=width/10*4.8, y=height/10*3) return entries def create_labels(all_lbls): labels = {} labels['user_lbl'] = Label(window, text='用户名:', bg=background_colour, fg=text_colour) labels['user_lbl'].place(x=width/10*3.8, y=height/10*2.5) labels['pwd_lbl'] = Label(window, text='密码:', bg=background_colour, fg=text_colour) labels['pwd_lbl'].place(x=width/10*3.8, y=height/10*3) return labels def main(details): result_store = [False] # 用列表存储结果 all_ents = ["username", "password"] all_lbls = ["user_lbl", "pwd_lbl"] entries = create_entries(all_ents) labels = create_labels(all_lbls) all_btn = insert_btn_commands(entries, details, result_store) buttons = create_buttons(all_btn) window.mainloop() # 获取最终验证结果 print("验证结果:", result_store[0]) test_details = {"admin": "123456", "user": "password"} main(test_details)
方法3:全局变量(不推荐)
用全局变量存储结果,但会导致代码逻辑混乱,仅适合极简单的场景。
import tkinter as tk from tkinter import Label, Button, Entry width = tk.Tk().winfo_screenwidth() height = tk.Tk().winfo_screenheight() background_colour = "#f0f0f0" text_colour = "#333333" window = tk.Tk() authenticated_result = False # 全局变量 def get_entry_values(entries): username = entries['username'].get() password = entries['password'].get() return username, password def authenticate(entries, details): global authenticated_result # 声明使用全局变量 username, password = get_entry_values(entries) authenticated_result = details.get(username) == password print("Authenticated" if authenticated_result else "Incorrect") label_pos = [width / 10 * 4.8, height / 10 * 3.5] wrong = Label(window, text='Incorrect', bg=background_colour, fg=text_colour) correct = Label(window, text='Authenticated', bg=background_colour, fg=text_colour) if authenticated_result: wrong.destroy() correct.place(x=label_pos[0], y=label_pos[1]) else: correct.destroy() wrong.place(x=label_pos[0], y=label_pos[1]) def insert_btn_commands(entries, details): all_btn = [{'text': 'Submit', 'pos': [width / 10 * 7.3, height / 10 * 4.5], 'command': lambda: authenticate(entries, details)}] return all_btn # 其余create_buttons、create_entries、create_labels、main函数与方法2类似 # main函数中可直接访问authenticated_result变量
总结
优先选择类封装的方式,代码结构清晰、状态管理规范;小型脚本可选用可变对象存储;尽量避免使用全局变量,防止代码逻辑混乱。
内容的提问来源于stack exchange,提问作者Charlie
相关产品推荐
相关产品推荐

