Reputation: 59
I have an issue, I created a table of buttons using a loop, and I saved the button's names in a list, now I want to change the text of the buttons when one button is clicked. I don't konw how.
this is the loop where i create the table
def grid(n):
i = n*n
for widget in LeftFrame.winfo_children():
widget.destroy()
for i in range(n):
for row in range(n):
for col in range(n):
button = Button(LeftFrame, text=' ', width=12, height=6, command=lambda: checker(button, i))
button.grid(row=row, column=col)
button_identities.append(button)
and this is the function on click of the button
def checker(buttons, i):
print(i)
global click, button_identities
print(button_identities)
bname = (button_identities[i])
print(bname)
if buttons["text"] == ' ' and click == True:
buttons["text"] = 'X'
click = False
# scorekeeper()
elif buttons['text'] == ' ' and click == False:
buttons['text'] = 'O'
click = True
# scorekeeper()
there is a method to check the text from the button name in the last function
Upvotes: 0
Views: 373
Reputation: 6156
so this is my take on this issue:
from tkinter import Tk, Button
root = Tk()
class EditableButton(Button):
def __init__(self, parent, row, col):
Button.__init__(self, parent)
self.parent = parent
self.row = row
self.col = col
self.tracker = 0
self.name_list = ['apple', 'pear']
print(len(self.name_list))
self.button = Button(self.parent, text=self.name_list[self.tracker], command=self.change_text)
self.button.grid(row=self.row, column=self.col)
def change_text(self):
if self.tracker < len(self.name_list) - 1:
self.tracker += 1
else:
self.tracker = 0
self.button.config(text=self.name_list[self.tracker])
n = 3
for row in range(n):
for col in range(n):
button = EditableButton(root, row, col)
root.mainloop()
basically what happens is You make a class that is like a template for buttons and each class object created by the loop is independent, each of them has their own spot in memory, so whenever You press the button it only calls the function in its own class
Upvotes: 0
Reputation: 7680
Try this:
from functools import partial
def grid(n):
for widget in LeftFrame.winfo_children():
widget.destroy()
for i in range(n):
for row in range(n):
for col in range(n):
button = Button(LeftFrame, text=' ', width=12, height=6)
# Assign the button a command
command = partial(checker, button)
button.config(command=command)
button.grid(row=row, column=col)
button_identities.append(button)
def checker(button):
# The argument is a button
global click
# If the cell is empty
if button.cget("text") == " ":
# If Xs are you play
if click:
# Change the text of the button
button.config(text="X")
click = False
# If Os are to play
else:
# Change the text of the button
button.config(text="O")
click = True
I usually use <widget>.cget("<parameter>")
to get the parameter out of a widget and <widget>.config(parameter=<new value>)
to assign it a new value. Also you can use functools.partial
to pass in arguments for the button command.
Upvotes: 1