Dynamic Handling of buttons in Tkinter


Tkinter dynamic buttons creation using range or a list with button reference management


Buttons can be created dynamically and can be referred for handling click events. Such requirements may occur when we are not sure how many buttons are required and how the events are to be handled.

Creating buttons dynamically

Dynamic creation of buttons
We can set a variable to any integer and based on this value , number of buttons will be created. The text on the buttons should display the (unique ) number of the button.
import tkinter  as tk 
from tkinter import *
my_w = tk.Tk()
my_w.geometry("200x200")  # Size of the window 
my_w.title("www.plus2net.com")  # Adding a title

n=10 # number of buttons
i=3
for j in range(n):
    e = Button(my_w, text=j) 
    e.grid(row=i, column=j) 
            
my_w.mainloop()  # Keep the window open

Reading the data written on the button

Reading button data dynamically on Click
We can read the value written on the button and display the same on button click. Note that the value we can’t use directly as it will always store the last value of the loop. So each button ( time ) we will assign the value to another variable to pass it through loop.
import tkinter  as tk 
from tkinter import *
my_w = tk.Tk()
my_w.geometry("200x200")  # Size of the window 
my_w.title("www.plus2net.com")  # Adding a title

my_str = tk.StringVar()
l1 = tk.Label(my_w,  textvariable=my_str, width=10 )
l1.grid(row=1,column=2,columnspan=6) 

def my_fun(k):
    my_str.set("Btn No is : "+ str(k) )    

n=10 # number of buttons
i=2
for j in range(n):
    e = Button(my_w, text=j,command=lambda k=j: my_fun(k)) 
    e.grid(row=i, column=j) 
            
my_w.mainloop()  # Keep the window open

Using string variables

Reading button string data & displaying
We will create one button for each element of a tuple of strings, on click of the button the string assigned to the button will be passed to another function and this function will display the string using one Label.
import tkinter as tk
my_w = tk.Tk()
my_w.geometry("200x200")  # Size of the window 
my_w.title("www.plus2net.com")  # Adding a title

my_str = tk.StringVar()
l1 = tk.Label(my_w,  textvariable=my_str, width=10 )
l1.grid(row=0,column=1,columnspan=5) 

def show_lan(my_language):
    my_str.set(my_language)

list_languages = ("PHP","Python","HTML","Tkinter")
var = 0


for language in list_languages:
    btn = tk.Button(my_w, text=language, command=lambda lan=language:show_lan(lan))
    btn.grid(row=1,column=var)
    var += 1

root.mainloop()

Disable Enable buttons

Enable or disable button after posting data
In above code we will add a feature that after the click of the button the string ( text ) of the button will be displayed and the button will be disabled for further click. When some other button is clicked then the previous button will be enabled and the new button will be disabled.

To do this we have to store the reference of the buttons in a list as these buttons are created dynamically. This list will be used to loop through and enable or disable each buttons by using the value of var ( the button which is clicked )
import tkinter as tk
my_w = tk.Tk()
my_w.geometry("300x200")  # Size of the window 
my_w.title("www.plus2net.com")  # Adding a title

my_str = tk.StringVar()
l1 = tk.Label(my_w,  textvariable=my_str, width=10 )
l1.grid(row=0,column=2,columnspan=6) 

def show_lan(my_language,var):
    my_str.set(my_language)
    #loop through all the buttons to enable or disable each one
    for i in range(len(buttons)):
        if i==var:
            buttons[i].config(state="disabled")
        else:
            buttons[i].config(state="normal")

list_languages = ("PHP","Python","HTML","Tkinter","Pandas")
var = 0

buttons = [] # to store button references 
#command=lambda index=index, n=n: appear(index, n)
for language in list_languages:
    btn = tk.Button(my_w, text=language, command=lambda var=var,lan=language:show_lan(lan,var))
    btn.grid(row=1,column=var)
    var += 1
    buttons.append(btn)  # adding button reference 
my_w.mainloop()

winfo_children() : List of all buttons

Managing Button Option
We can create a group of buttons and then access their options by using winfo_children().
We will create 10 buttons dynamically.
var =0
for i  in range(10):
    btn = tk.Button(my_w, text=str(i),font=font1)
    btn.grid(row=0,column=var,padx=5,pady=20)
    var += 1
We will add one more button with onClick event to trigger a function my_upd()
b1=tk.Button(my_w,text='Update Green',bg='lightgreen',command=lambda:my_upd())
b1.grid(row=1,column=0,columnspan=5)
The function my_upd() will update the options of the Buttons and change the background colour. As we are reading the text written over the button and converting the same to integer, we may get error if any button text we fail to convert to integer.

The button text Update Green can't be converted to integer. So we will use one try except code block to handle error.
def my_upd():
    for wgd in my_w.winfo_children(): # all widgets 
        try:
            if int(wgd['text']) %2 ==0: # if the number written is even number
                wgd['bg']='lightgreen'  # change the background colour
            else:
                wgd['bg']='lightpink'
        except:
            pass
Tkinter managing options of dynamically created buttons by changing background colour
Full code is here
import tkinter as tk
my_w = tk.Tk()
my_w.geometry('400x200')
my_w.title("www.plus2net.com")  # Adding a title
font1=('Times',14,'bold')
var =0
for i  in range(10):
    btn = tk.Button(my_w, text=str(i),font=font1)
    btn.grid(row=0,column=var,padx=6,pady=30)
    var += 1

def my_upd():
    for wgd in my_w.winfo_children(): # all widgets 
        try:
            if int(wgd['text']) %2 ==0: # if the number written is even number
                wgd['bg']='lightgreen'  # change the background colour
            else:
                wgd['bg']='lightpink'
        except:
            pass
        
b1=tk.Button(my_w,text='Update Green',bg='lightgreen',command=lambda:my_upd())
b1.grid(row=1,column=0,columnspan=5,padx=10,pady=10)

my_w.mainloop()
View and Download tkinter-button-dynamic ipynb file ( .html format )

Dynamically create Entry box with Label Dynamic Label Managing Geometry Dynamically managing Spinboxes
Subscribe to our YouTube Channel here


Subscribe

* indicates required
Subscribe to plus2net

    plus2net.com



    09-04-2022

    Thank you. Very helpful demonstration. I even liked the mistake towards the end and the correction

    25-10-2022

    Thank You so much sir/madam..
    You were my life saver. The logic in your code really helped me proceed with my project.
    THANKS A TON !!!

    26-11-2022

    Thank you very much for the solution to create multiple tkinter Buttons with for a loop. I searched and followed may pages, none works -- all buttons invoke the lambda function with the same argument. Your code works!
    The key is: k=j in 'command=lambda k=j: my_fun(k)' [as compared to 'command=lambda: my_fun(j), which does not work. Seems k=j creates a true copy of j.

    24-12-2022

    Yes, you are right, the variable k is unique to the button generated.

    Post your comments , suggestion , error , requirements etc here





    Python Video Tutorials
    Python SQLite Video Tutorials
    Python MySQL Video Tutorials
    Python Tkinter Video Tutorials
    We use cookies to improve your browsing experience. . Learn more
    HTML MySQL PHP JavaScript ASP Photoshop Articles FORUM . Contact us
    ©2000-2024 plus2net.com All rights reserved worldwide Privacy Policy Disclaimer