tkinter incrementally display integers on buttons when clicked

In a series of say 5 Button objects, I would like that the first clicked Button sees its 'text' parameter updated to the number 1. Then, when I click a second Button, no matter which one, I would like it to display 2, then 3, up to 5.

Here is my attempt, it keeps displaying 1 and does not iterate.

import tkinter as tk

root = tk.Tk()
root.geometry('300x200')
buttons = []

def callback(num):
    buttons[num].config(text=next(iter(range(1, 5))))

for i in range(5):
    buttons.append(tk.Button(root, text='?', width=6, height=3, command=lambda x=i: callback(x)))

for j in buttons:
    j.pack(side='left')

root.mainloop()

additional information: I might have difficulties to really understand how callback operates, using lambda instead of calling it directly, and a misuse of the latter might be the reason it is not working as expected. It is also the first time I am using next() and iter(), and might have done it wrong.

Upvotes: 1

Views: 105

Answers (2)

Henry Yik
Henry Yik

Reputation: 22503

Consider the below:

buttons[num].config(text=next(iter(range(1, 5))))

You are creating a new iterator every time you click the button. Instead, you should define it in global scope, and call next on it during each button click:

a = iter(range(1, 5))

def callback(num):
    buttons[num].config(text=next(a))

Upvotes: 1

Phoenixo
Phoenixo

Reputation: 2133

You need to separate your iterator definition and the next()calls, otherwise you were creating a new iterator each time.

You also need to put 6 in iter(range(1, 6)) if you want it to go up to 5.

Try this :

import tkinter as tk

root = tk.Tk()
root.geometry('300x200')
buttons = []
my_iter = iter(range(1, 6))

def callback(num):
    buttons[num].config(text=next(my_iter))

for i in range(5):
    buttons.append(tk.Button(root, text='?', width=6, height=3, command=lambda x=i: callback(x)))

for j in buttons:
    j.pack(side='left')

root.mainloop()

Upvotes: 2

Related Questions