0

I want to create multiple rows of tkinter widgets and I thought storing them in a dictionary would be a clean way to do this. I'm having trouble getting the callbacks for the buttons to work correctly though. With the code as is, the value passed to the button callback is always E and I can't see why that is. How do I pass the correct key to the callback please - i.e. A for the first row, B for the second etc?

import tkinter as tk

NUM_ROWS = 5
BOLD_FONT = ("calbri", 16, "bold")
NORMAL_FONT = ("calbri", 16, "normal")


def submit():
    print("you win")


def clear(key):
    print(key)
    # widgets[key]["factor_field"].delete(0,"end")
    # widgets[key]["factor_field"].insert(0, key)


data = {}
widgets = {}

root = tk.Tk()

# Build widgets
for i in range(NUM_ROWS):
    key = chr(i + 65)
    this_row = widgets[key] = {}
    this_row["label"] = tk.Label(root, text=key, font=BOLD_FONT)
    this_row["label"].grid(row=i, column=0, padx=5, pady=10)
    this_row["factor_field"] = tk.Entry(root, width=60, font=NORMAL_FONT)
    this_row["factor_field"] .grid(row=i, column=1, padx=5, pady=10)
    this_row["target_node_field"] = tk.Entry(root, width=5, font=NORMAL_FONT)
    this_row["target_node_field"].grid(row=i, column=2, padx=5, pady=10)
    this_row["clear_button"] = tk.Button(root, text="Clear", command=lambda: clear(
        key), font=BOLD_FONT).grid(row=i, column=3, padx=5, pady=10)

submit_button = tk.Button(root, text="Submit", command=submit,
                          font=BOLD_FONT).grid(row=NUM_ROWS + 1, column=0, padx=5, pady=10)

print(widgets)
root.mainloop()
1
  • 1
    Use command=lambda key=key: clear(key) instead of command=lambda: clear(key) . Commented Sep 6, 2020 at 12:09

1 Answer 1

1

Use this:

this_row["clear_button"] = tk.Button(root, text="Clear", 
                                     command=lambda x=key: clear(x), 
                                     font=BOLD_FONT)
this_row["clear_button"].grid(row=i, column=3, padx=5, pady=10)

In your current code, the value for the key variable is fixed at E after the for loop has completed. As a result, your existing lambda function will always call clear('E').

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.