Skip to content
Advertisement

Tkinter Events in for loop

I am currently working on an app with tkinter, which is basically PHPMyadmin. After the login I want to display all the databases in Labels and attach an Event to them. Well it kinda worked…

Currently this code just prints out all the databases when clicked, but I want it to print just its own name. If it is possible, I don’t want to create the events. Is there a way to “customize” Events?

for x in mycursor:
    if x == "":
        ""
    else:
        y += ''.join(x) + ","
        def event(event):
            print(y)
    
        label = Label(dbframe, text=x)
        label.bind("<Button-1>", event)
        label.configure(font="Helvetica 10 bold")
        label.pack()

Advertisement

Answer

bind sends event with information which widget was clicked and you can get text from Label using event.widget["text"]


Minimal working example:

import tkinter as tk  # PEP8: `import *` is not preferred

# --- functions ---  # PEP8: all functions at the beginning

def my_function(event):
    print("widget:", event.widget['text'])

# --- main ---

root = tk.Tk()

for name in ['Table A', 'Table B', 'Table C']:
    label = tk.Label(root, text=name)
    label.bind("<Button-1>", my_function)
    label.pack()
    
root.mainloop()    

PEP 8 — Style Guide for Python Code


EDIT:

If you want to send to function other value then you can use lambda to bind function with value.

If you use lambda in loop then you need first assign this value to variable in lambda

import tkinter as tk  # PEP8: `import *` is not preferred

# --- functions ---  # PEP8: all functions at the beginning

def my_function(event, text):
    #print("widget:", event.widget['text'])
    print("text  :", text)

# --- main ---

root = tk.Tk()

for name in ['Table A', 'Table B', 'Table C']:
    label = tk.Label(root, text=name)
    label.bind("<Button-1>", lambda event, text=name:my_function(event, text))  # you have to use `text=name` when you use in `for`-loop
    label.pack()
    
root.mainloop()    

Or you can assign value to label – ie. label.own_value = "..." and later get it as event.widget.own_value

import tkinter as tk  # PEP8: `import *` is not preferred

# --- functions ---  # PEP8: all functions at the beginning

def my_function(event):
    #print('widget:", event.widget['text'])
    print("event :", event.widget.own_value)

# --- main ---

root = tk.Tk()

for name in ['Table A', 'Table B', 'Table C']:
    label = tk.Label(root, text=name)
    label.own_value = f"Hello {name}"
    label.bind("<Button-1>", my_function)
    label.pack()
    
root.mainloop()    
User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement