Iain
Iain

Reputation: 41

How to identify labels on a Python Tkinter Tab in the event handler

I am placing labels on a Tab in Tkinter with a for loop. How can I identify in the event handler which label was clicked (or its loop index)? I guess it is functionally similar to a ListBox but without the formatting restrictions. I might want to put the labels in a circle or place them diagonally. I tried finding the coordinates of the label but these are available only if the tab is the first one visible or the tab is redrawn when made active. Also the x, y passed in the event handler is the x, y within the label which does not help to identify the label.

I could copy the label code about 10 times and and have about 10 event handlers. This would work but this is no longer 1970!

Perhaps I could bind a handler to the tab canvas and identify the label from its coordinates. The label would need to be on the first tab or the tab drawn when active.

Perhaps I could create a different event handler for each label by holding the event handlers in an array. I would need an event handler for each label. The code would need to change if the number of labels changed.

I am currently trying a label with ''. Would using buttons with command be easier?

What simple part of Python am I missing? I cannot be the first person to need this! Any help or advice would be appreciated.

Upvotes: 0

Views: 985

Answers (2)

Bryan Oakley
Bryan Oakley

Reputation: 386010

When you bind events, the function receives an object that includes a reference to the widget that received the event. In the following example, notice how it uses event.widget to refer to the widget that was clicked on.

import tkinter as tk

def update_label(event):
    event.widget.configure(text="You clicked me")

root = tk.Tk()

for i in range(10):
    l = tk.Label(root, text="Click me", width=20)
    l.pack()
    l.bind("<1>", update_label)

root.mainloop()

Upvotes: 1

figbeam
figbeam

Reputation: 7176

You can save a reference to the label text for each label widget in a dict.

import tkinter as tk
from tkinter import ttk
 
root = tk.Tk()
root.geometry('+800+50')

notebook = ttk.Notebook(root, width=300, height=200, padding=[10,10,10,10])
notebook.pack()
tab_one = tk.Frame(notebook, bg='wheat')
notebook.add(tab_one, text='Cheese', padding=[10,10,10,10])
tab_two = tk.Frame(notebook, bg='mint cream')
notebook.add(tab_two, text='Misc.', padding=[10,10,10,10])

def clicked(event):
    print('Clicked:', name_dict[event.widget])

# Populating Cheese tab with clickable Labels
name_list = ['Cheddar', 'Ilchester', 'Limburger']
name_dict = {}
for index, name in enumerate(name_list):
    a = tk.Label(tab_one, width=10, text=name, bg='peru')
    a.grid(row=index, column=0, padx=5, pady=5)
    name_dict[a] = name     # Save references in a dict
    a.bind('<Button-1>', clicked)

tk.Label(tab_two, text='Just some text...', bg='powder blue').pack(anchor='nw')

root.mainloop()

Is this what you had in mind?

Upvotes: 1

Related Questions