Heikki
Heikki

Reputation: 351

Tkinter, how to get/return value by clicking a button in for-loop?

Here is my code:

from tkinter import *

master = Tk()

row_count = 0
for i in range(5):
    frame1 = LabelFrame(master).pack()
    label1_label = Label(frame1, text=row_count).pack()
    button1 = Button(frame1, text='Give/return/get value').pack()

    row_count = row_count + 1

master.mainloop()

I want to get or return corresbonding value buy clicking a button so that I can use it in some other function. For example if I click the button under 3 it would return 3.

Upvotes: 0

Views: 1118

Answers (1)

Novel
Novel

Reputation: 13729

You need to make a closure. You can do this with def, partial, lambda, or (neatest) a custom widget.

Using standard closure with def:

from tkinter import *

master = Tk()

for i in range(5):
    frame1 = LabelFrame(master) # named Widgets must use 2 lines to define them!
    frame1.pack()
    Label(frame1, text=i).pack()
    def function(number=i):
        print(number, 'clicked')
    Button(frame1, text='Give/return/get value', command=function).pack()

master.mainloop()

Using partial to make the closure:

from tkinter import *
from functools import partial

def function(number):
    print(number, 'clicked')

master = Tk()

for i in range(5):
    frame1 = LabelFrame(master) # named Widgets must use 2 lines to define them!
    frame1.pack()
    Label(frame1, text=i).pack()
    Button(frame1, text='Give/return/get value', command=partial(function, i)).pack()

master.mainloop()

Using lambda to make the closure:

from tkinter import *

def function(number):
    print(number, 'clicked')

master = Tk()

for i in range(5):
    frame1 = LabelFrame(master) # named Widgets must use 2 lines to define them!
    frame1.pack()
    Label(frame1, text=i).pack()
    Button(frame1, text='Give/return/get value', command=lambda i=i:function(i)).pack()

master.mainloop()

Using a custom widget:

from tkinter import *

class Heikki(LabelFrame):
    def __init__(self, master=None, number=0, **kwargs):
        super().__init__(master, **kwargs)
        self.number = number
        Label(self, text=number).pack()
        Button(self, text='Give/return/get value', command=self.function).pack()

    def function(self):
        print(self.number, 'clicked')

master = Tk()

for i in range(5):
    Heikki(master, i).pack()

master.mainloop()

Upvotes: 3

Related Questions