1

I got a dict like this:

dict = {"site1": link to site1,
        "site2": link to site2,
        "site3": link to site3,
        [...]
        }

and I don't know in advance how many sites will be inside the dict.

What I'm trying to achieve is binding different links to Labels created dynamically inside a for loop. I want to make a window with a list of names and when you click the name it will redirect you on the site.

I'm using this example below but without success.

from tkinter import Tk, Label, StringVar
import webbrowser

root = Tk()

list1 = ["site1-google","site2-facebook"]
list2 = ["google.com", "fb.com"]

for v1, v2 in zip(list1, list2):

    item_values = '{}'.format(v1)
    sv = StringVar()
    lbl = Label(root, width="100", height="2",textvariable=sv)
    lbl.pack()
    lbl.bind("<Button-1>", lambda e: callback(v2))

    

    sv.set(item_values)
    
    def callback(url):
        webbrowser.open_new(url)

root.mainloop()

When I run the program it just bind the "last site" from list2 to all the freshly created Labels.

I read somewhere that lambda is late-binding, so it will bind every time the last value of the given list, but I don't know how to fix the problem!

How do I go on?

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
  • You probably don't need a `callback` function it can be done without it just do `lbl.bind("", lambda e, url=v2: webbrowser.open_new(url))` – Saad Jul 01 '20 at 19:10
  • Well, that worked out! I really appreciate it man! May I ask you how does this solution work? I'm still learning and couldn't find documentation about it, you came and resolved with a single line.! – Luca Gualandri Jul 01 '20 at 23:06
  • When using `lambda` in a loop we need to pass arguments that are used in the lambda function otherwise only the last value of the for loop is considered *(You can further read [here](https://stackoverflow.com/questions/10865116/tkinter-creating-buttons-in-for-loop-passing-command-arguments))* – Saad Jul 02 '20 at 09:49

0 Answers0