pythondictionarytkinter

python Get a specific value of a label inside a loop


Simple example of the problem

# import * is bad, this is just an example
from tkinter import *

root = Tk()
root.minsize(200, 200)

dict = {"1": ("banane 1", "fresh"), "2": ("banane 2", "not fresh"), "3": ("banane 3", "rotten")}

# Right click label
def openMenuGroup(self):
   menuGroup.post(self.x_root, self.y_root)
           
def closeMenuGroup():
    menuGroup.unpost()
           
menuGroup = Menu(root, tearoff=0)

for key, value in dict.items():
    name, quality = value
    lab = Label(text=name)
    lab.quality = quality
    lab.bind("<Button-3>", openMenuGroup)
    lab.pack()

menuGroup.add_command(label="Check quality", command=lambda:checkQuality(lab.quality))
menuGroup.add_command(label="Close", command=closeMenuGroup())
        
def checkQuality(self):
   print(self)
   
mainloop()

When you click on Check quality, it will always return "rotten" (last iteration). How can I get the correct lab.quality for each of those label ?


Solution

  • You need to create the popup menu inside openMenuGroup() instead and pass the correct quality to checkQuality():

    from tkinter import *
    
    root = Tk()
    root.minsize(200, 200)
    
    dict = {"1": ("banane 1", "fresh"), "2": ("banane 2", "not fresh"), "3": ("banane 3", "rotten")}
    
    def checkQuality(quality):
        print(quality)
    
    # Right click label
    def openMenuGroup(event):
        # create menu here
        menuGroup = Menu(root, tearoff=0)
        # use event.widget to reference the label that trigger this function
        menuGroup.add_command(label="Check quality", command=lambda:checkQuality(event.widget.quality))
        menuGroup.add_command(label="Close", command=menuGroup.unpost)
        menuGroup.post(event.x_root, event.y_root)
    
    for key, value in dict.items():
        name, quality = value
        lab = Label(text=name)
        lab.quality = quality
        lab.bind("<Button-3>", openMenuGroup)
        lab.pack()
    
    mainloop()