You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 21:39:37