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)