Python Forum
Returning data on button click by buttons created by a loop
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Returning data on button click by buttons created by a loop
#1
Hi there,

Born again coding newb here .... (2 days in so far....)

I have a GUI that has buttons created based upon the number of lines from a csv file. That creation is no problem.

My issue is I'd like to pass on some form of useful information on a button click pertaining to each individual button.


Here is my simplified snippet of code:

# import
from tkinter import *

# window
root = Tk()
root.geometry('600x400')

def button_click(args):
	Label(root, text = args).pack()

for i in range(5):
	button = Button(root, text = "Button " + str(i), command=lambda: button_click([i]))
	button.pack()

# run
root.mainloop()
Regardless of which button clicked, it will return the last value of i in the loop (4) . I'd like it to return the value of the button as it was created (either as a string or integer)


Thanks!
Reply
#2
Check
https://stackoverflow.com/q/3431676/4046632
and
https://stackoverflow.com/q/2295290/4046632
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#3
lambda creates a closure, a combination of a function and a context. In your example the closer contains the function button_click() and the variable i. Each button calls a different lambda, but each lambda calls the same function and passes the same variable.

Enclosing a variable with a function is very powerful, but sometimes it just gets in the way. If you just want to bind a function call with an argument, a better tool is a partial.

https://docs.python.org/3/library/functools.html

This is your code using a partial instead of lambda.
import tkinter as tk
from functools import partial


def button_click(args):
    tk.Label(root, text=args).pack()


root = tk.Tk()
root.geometry("600x400")
for i in range(5):
    tk.Button(root, text=f"Button {i}", command=partial(button_click, i)).pack()
root.mainloop()
If you want to use lambdas, you can accomplish the same thing by creating a variable local to the lambda enclosure.
import tkinter as tk


def button_click(args):
    tk.Label(root, text=args).pack()


root = tk.Tk()
root.geometry("600x400")
for i in range(5):
    tk.Button(root, text=f"Button {i}", command=lambda x=i: button_click(x)).pack()
root.mainloop()
This code works because the lambda expression creates a variable "x" that only exists in the closure created by the lambda. Like before each button calls a different lambda and each lambda calls button_click. The difference is each lambda enclosure as its own variable x instead of a shared variable i.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  I think I need to delete input data because returning to start fails thelad 2 1,089 Sep-24-2024, 10:12 AM
Last Post: thelad
  Returning Column and Row Data From Spreadsheet knight2000 0 1,085 Oct-22-2023, 07:07 AM
Last Post: knight2000
  WHILE LOOP NOT RETURNING USER INPUT AFTER ZerroDivisionError! HELP! ayodele_martins1 7 2,483 Oct-01-2023, 07:36 PM
Last Post: ayodele_martins1
  Button to stop while loop from another script Absolutewind 5 2,855 Sep-25-2023, 11:20 PM
Last Post: deanhystad
  Basic SQL query using Py: Inserting or querying sqlite3 database not returning data marlonbown 3 3,107 Nov-08-2022, 07:16 PM
Last Post: marlonbown
  How to break out of a for loop on button press? philipbergwerf 6 3,537 Oct-06-2022, 03:12 PM
Last Post: philipbergwerf
  For Loop Returning 3 Results When There Should Be 1 knight2000 12 6,024 Sep-27-2021, 03:18 AM
Last Post: SamHobbs
  Build a matrix by pressing buttons of an interface in Tkinter which extract data from juandiegopulla 1 2,912 Sep-13-2021, 07:28 PM
Last Post: deanhystad
  returning values in for loop Nickd12 4 22,617 Dec-17-2020, 03:51 AM
Last Post: snippsat
  Scripting: Multiple Votes With a Single Click or Button Ovidiu 0 1,779 Jul-07-2020, 10:51 AM
Last Post: Ovidiu

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020