Python creating dynamic button

Question:

I have an array, which holds some URLs.

I essentially want to create a button, within a tk, that opens the url in a browser.

So far, i’ve got the button to create, however, when i run the .py file, it seems that the function to open the page is being hit – not prepared for the button.

import tkinter as tk
import webbrowser as Web
urls = [[1, 'http://www.google.co.uk','Google'],[2, 'http://www.bbc.co.uk','BBC']];

def urlOpen(target):
    Web.open(target)

window = tk.Tk()
window.overrideredirect(1)
window.update_idletasks()    

for url in urls:
    urlTarget = url[0]
    labelurl = tk.Button(window, text=url[2], height = 2, command = urlOpen(url[1]), width = 10)
    labelurl.grid(row = url[0] + 1 , column = 1)

close = tk.Button(window, text = 'Quit',  command = window.destroy, width = 10)
close.grid(row = len(urls) + 2, column = 1)
window.mainloop()

I know, using OOP python would be easier – however i’m new to this, and still picking things up!

Asked By: oliversarfas

||

Answers:

What’s happening is that you’re calling the function when you create the button — not when it gets clicked:

labelurl = tk.Button(window, text=url[2], height = 2, command = urlOpen(url[1]), width = 10)

What you need is to defer the function call:

for url in urls:
    onclick = lambda url=url[1]: urlOpen(url)
    labelurl = tk.Button(window, text=url[2], height = 2, command = onclick, width = 10)
    labelurl.grid(row = url[0] + 1, column = 1)

Here I’ve created a new function for each url — when called with no arguments, that function will call urlOpen with the correct url. (Note that I’m using the standard lambda x=y: x trick to make sure that the lambda function picks up the correct url in the loop).

Answered By: mgilson
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.