Reputation: 17
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
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
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