Python Forum
Problem with buttons - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: GUI (https://python-forum.io/forum-10.html)
+--- Thread: Problem with buttons (/thread-10089.html)



Problem with buttons - Epilepsy - May-12-2018

Hi there, i have a problem, I hope you can help me, my problem:
I'm gridding some buttons with for, then i add a value and some command to do, but when i do the command, always give me the last value, the code:

from tkinter import *
import tkinter as tk

def write_slogan(v):
    print(v)

root = tk.Tk()
frame = tk.Frame(root)
frame.pack()

for k in range(0,11,1):
    btn = tk.Button(frame, text=str(k), command=lambda: write_slogan(k))
    btn.pack(side=tk.LEFT)

root.mainloop()
What i'm doing wrong?


RE: Problem with buttons - Barrowman - May-12-2018

You need to bind the buttons to an event and call the command differently.
Here is the code as I have altered it.
from tkinter import *
import tkinter as tk
 
def write_slogan(event):
    v= event.widget['text']
    print(v)
 
root = tk.Tk()
frame = tk.Frame(root)
frame.pack()

for k in range(0,11,1):
    btn = tk.Button(frame, text=str(k))
    btn.bind("<Button-1>", write_slogan)
    btn.pack(side=tk.LEFT)
 
root.mainloop()



RE: Problem with buttons - woooee - May-12-2018

btn is overwritten on each pass through the for, so btn contains the last button after the loop is finished. Use partial to send the button number to the function. See my post at https://python-forum.io/Thread-Tkinter-Tic-Tac-Toe?highlight=tkinter for an example of how it is done. You can ignore/remove the class (self.) in your program, but you will have to use a list or dictionary to store the button instances if you want to use them in the function to modify the buttons. Modify your code and post back if you have problems.


RE: Problem with buttons - Larz60+ - May-12-2018

write it this way:
from tkinter import *
import tkinter as tk


def write_slogan(v):
    print(v)


root = tk.Tk()
frame = tk.Frame(root)
frame.pack()
btns = []

for k in range(0, 11, 1):
    btns.append(tk.Button(frame, text=str(k), command=lambda: write_slogan(k)))
    btns[k].pack(side=tk.LEFT)

root.mainloop()



RE: Problem with buttons - Barrowman - May-12-2018

(May-12-2018, 06:05 PM)Larz60+ Wrote: write it this way:
from tkinter import *
import tkinter as tk


def write_slogan(v):
    print(v)


root = tk.Tk()
frame = tk.Frame(root)
frame.pack()
btns = []

for k in range(0, 11, 1):
    btns.append(tk.Button(frame, text=str(k), command=lambda: write_slogan(k)))
    btns[k].pack(side=tk.LEFT)

root.mainloop()
Sorry but it has the same problem as Epilepsy had. He needs to bind the buttons to an event. See post #2


RE: Problem with buttons - Larz60+ - May-12-2018

Barrowman, yes, so a combination of both:
from tkinter import *
import tkinter as tk


def write_slogan(event):
    item = event.widget
    t = item.cget('text')
    print(t)


root = tk.Tk()
frame = tk.Frame(root)
frame.pack()
btns = []

for k in range(0, 11, 1):
    btns.append(tk.Button(frame, text=str(k)))
    btns[k].pack(side=tk.LEFT)
    btns[k].bind("<Button-1>", write_slogan)

root.mainloop()
or cleaner:
import tkinter as tk

root = tk.Tk()

def write_slogan(event):
    btn = event.widget
    print(btn.cget('text'))

for i in range(10):
    b = tk.Button(root, text='{}'.format(i))
    b.grid(row=0, column=i)
    b.bind("<Button-1>", write_slogan)

root.mainloop()