Skip to content
Advertisement

How to assign different URLs to tkinter labels generated in for loop?

Im using a function to generate my labels and each label must open different URLs. So far no matter what text i click it opens the last URL

from tkinter import *
import webbrowser

def callback(url):
    webbrowser.open_new(url)
    
def write_hello():
        
    tuples = (('bing ', 'https://bing.com'), ('youtube ', 'https://youtube.com'), ('google ', 'google.com'))

    for label_text, url in tuples:
        
        text = mytext.cget("text") + 'n' + str(label_text)
        mytext.pack()
        mytext.configure(text=text)
        mytext.bind("<Button-1>", lambda e, _url=url: callback(_url))


    
root = Tk()

button = Button(root, text = "Hello!", command = write_hello )
button.pack()
mytext=Label(root,bg="pink",width=30,height=20)

root.mainloop()

Advertisement

Answer

Try the following

from tkinter import *
import webbrowser

def callback(event, url):
    print(url)
    webbrowser.open_new(url)
    
def write_hello():
        
    tuples = (('bing ', 'https://bing.com'), ('youtube ', 'https://youtube.com'), ('google ', 'google.com'))

    for label_text, url in tuples:
        new_label = Label(root)
        new_label['text'] = label_text
        new_label.bind("<Button-1>", lambda e,x=url: callback(e,x))
        new_label.pack()
    
root = Tk()

button = Button(root, text = "Hello!", command = write_hello )
button.pack()
mytext=Label(root,bg="pink",width=30,height=20)

root.mainloop()

As per your code example, after you press the “Hello!” button, new labels will be created which contain the URL name and when clicked on will take you to the correct webpage. The difficulty here is caused by using labels rather than buttons. The bind method for the clicking on the label sends an “event” parameter to the function called which needs to be taken in to account when creating your lambda function.

With regards to your related question, infinite loops and tkinter GUI’s don’t play well together as the infinite loop will block the GUI from reacting to user events. If you need to do something in an infinite loop, consider looking at threads (outside of the scope of this specific question)

User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement