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

Tkinter动态生成按钮后,如何获取被点击按钮的文本?

Fix: Get Text of Dynamically Generated Buttons in Tkinter

Ah, this is a classic scoping issue with Tkinter buttons created in loops! The problem is that all your buttons are referencing the same global button_name variable, which gets overwritten every time the loop runs—by the end, it only holds the text of the last button. Here's how to fix it cleanly, without relying on global variables:

The Core Issue

When you bind command=create_window to each button, Python doesn't capture the current value of name at the time the button is created. Instead, it creates a reference to the variable name itself. By the time you click any button, the loop has finished, and name is set to the last item in your list.

Solution 1: Use Lambda with Default Arguments

We can pass the button's text directly to create_window using a lambda that captures the current name value via a default parameter. This "freezes" the value at the time the button is created.

First, modify your create_window function to accept a button_text parameter:

def create_window(button_text):  # Add button_text parameter
    def fill_fields():
        with open ("Passwords.txt", 'r') as data_file:
            data = data_file.readlines()
            for i in data:
                names = i.split("|")
                if names[0] == button_text:  # Use the passed button_text instead of global
                    Website_.insert(0, names[0])
                    Username_.insert(0, names[1])
                    Password_.insert(0, names[2])
    # Rest of your create_window code remains the same

Then, update how you create your buttons in the loop:

# Remove the global button_name variable entirely
button_name = ""  # Delete this line

# In your loop, change the command to use a lambda with default argument
button_ = Button(frame,text=name, font=("Helvetica", 12), width=16, bg="white", fg="black", 
                 command=lambda x=name: create_window(x))  # x=name captures current value
# Remove this line too: button_name = button_.cget('text')

Solution 2: Use functools.partial (Cleaner Alternative)

If you prefer a more readable approach, use functools.partial to bind the name value to the create_window function:

First, import partial at the top of your script:

from functools import partial

Then, modify the button creation line:

button_ = Button(frame,text=name, font=("Helvetica", 12), width=16, bg="white", fg="black", 
                 command=partial(create_window, name))  # Bind name as the first argument

This works exactly like the lambda method but is more explicit, especially for newer Python developers.

Why This Works

Both methods ensure that each button's command function holds a reference to the specific name value that existed when the button was created, not the variable that gets updated through the loop. This eliminates the dependency on a global variable and fixes the "always last button text" problem.

Full Modified Code

Here's your code with the lambda solution applied (removed global variables and updated command bindings):

from tkinter import *
from functools import partial  # Uncomment if using the partial solution

def click():
    window = Tk()
    window.geometry("600x500")
    frame = Frame(window, bg = "#161853", width = 600, height = 500)
    row_ = 0
    column_ = 0
    list = []
    with open ("Passwords.txt", 'r') as data_file:
        data = data_file.readlines()
        for i in data:
            names = i.split("|")
            list.append(names[0])
    for i in range(len(list)):
        name = list[i]
        # Using lambda with default argument
        button_ = Button(frame,text=name, font=("Helvetica", 12), width=16, bg="white", fg="black", 
                         command=lambda x=name: create_window(x))
        # OR using partial (uncomment below and comment lambda line):
        # button_ = Button(frame,text=name, font=("Helvetica", 12), width=16, bg="white", fg="black", 
        #                  command=partial(create_window, name))
        button_.grid(row=row_, column=column_, padx=(25, 0), pady=(25,0))
        column_ += 1
        if column_ == 3:
            row_ += 1
            column_ = 0
    frame.pack(fill="both", expand=True)
    window.mainloop()

def create_window(button_text):
    def fill_fields():
        with open ("Passwords.txt", 'r') as data_file:
            data = data_file.readlines()
            for i in data:
                names = i.split("|")
                if names[0] == button_text:
                    Website_.insert(0, names[0])
                    Username_.insert(0, names[1])
                    Password_.insert(0, names[2])
    def save_password():
        if Website_.get() == "" or Username_.get() == "" or Password_.get() == "":
            window = Tk()
            Error_Message = Label(window, text = "Error! Please fill all the above fields.", bg="red", fg="white", font=("Arial", 16))
            Error_Message.pack()
            window.mainloop()
        else:
            with open("Passwords.txt" , 'a') as file:
                file.write(Website_.get() + "|" + Username_.get() + "|" + Password_.get() + "\n")
    window = Tk()
    window.geometry("600x500")
    window.configure(bg="#161853")
    window.minsize(600, 500)
    frame = Frame(window, bg="#161853")
    frame.rowconfigure(2, weight=1)
    frame.columnconfigure([0, 1, 2], weight=1)
    Text = Label(frame, text="Save your password here", font=("Helvetica", 14), fg="white", bg="#161853")
    Text.grid(row=0, column=1, pady=(0,25))
    Website = Label(frame, text="Website:", font=("Helvetica", 14), fg="white", bg="#161853")
    Website.grid(row=1, column=0, padx=(0, 15), pady=(0,20))
    Website_ = Entry(frame, width=25)
    Website_.grid(row=1, column=1, pady=(0, 20))
    Username = Label(frame, text="Username/Email:", font=("Helvetica", 14), fg="white", bg="#161853")
    Username.grid(row=2, column=0, padx=(0, 15), pady=(0, 20))
    Username_ = Entry(frame, width=25)
    Username_.grid(row=2, column=1, pady=(0, 20))
    Password = Label(frame, text="Password:", font=("Helvetica", 14), fg="white", bg="#161853" )
    Password.grid(row=3, column=0, padx=(0, 15), sticky="s")
    Password_ = Entry(frame, width=25)
    Password_.grid(row=3, column=1, pady=(0, 30), sticky="s")
    Generate = Button(frame, text="Generate Password", font=("Helvetica", 12), width=16)
    Generate.grid(row=3, column=2, sticky="s")
    Save = Button(frame, text="Save Password", font=("Helvetica", 12), width=14, command=save_password)
    Save.grid(row=4, column=1)
    frame.place(relx=0.5, rely=0.5, anchor="center")
    fill_fields()
    window.mainloop()

内容的提问来源于stack exchange,提问作者Newbie

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 13:37:29