Я осмотрел SO и попробовал предложенные решения, но я не могу изменить text
любого button
, который я сделал, используя двойную петлю for
.
Циклы есть, поэтому я могу добавить их к list
из lists
из buttons
, чтобы я мог (предположительно) получить к ним удобный доступ через вложенный список, вызвав board_button[2][3]
или что-то еще.Они также динамически создаются после того, как пользователь вводит board_size
, так что он генерирует сетку из кнопок nxn, так что это так.Все это делается внутри метода класса, и есть еще один метод класса, который должен изменить button
'text
, когда он вызывается кнопкой.
Я пытался использовать предлагаемые решения здесь , но на самом деле ни одно из них не помогло моей проблеме.
Прошу прощения за длинный блок кода, но я, честно говоря, думаю, способ, которым я его сделал, мог способствовать проблеме и дать более глубокое понимание в результате.
from tkinter import filedialog
from tkinter import *
class MainWindow(Frame):
board_size = None
file_input = None
board_buttons = None
board_strvars = None
row = []
def __init__ (self, parent):
Frame.__init__(self, parent)
# initialize widgets but don't show them yet
self.initWidgets()
# show the starting window
self.startWindow()
def generateBoard(self, to_forget=None):
# hides the groups of the method that called it
if to_forget != None:
for i in to_forget:
self.row[i].forget()
# get the board_size from user
self.board_size = int(self.size_entry.get())
# initialize text variables for each button
self.board_strvars = []
for i in range(self.board_size):
self.row_strvars=[]
for j in range(self.board_size):
var = StringVar()
var.set(" ")
self.row_strvars.append(var)
self.board_strvars.append(self.row_strvars)
# insert list of lists of buttons here
self.row[1].pack(fill=X)
self.board_buttons = []
for i in range(self.board_size):
self.row_buttons=[]
for j in range(self.board_size):
self.row_buttons.append(Button(self.row[1], textvariable=self.board_strvars[i][j], command=lambda:self.place(i, j)))
self.row_buttons[j].grid(row=i, column=j)
self.board_buttons.append(self.row_buttons)
# for solve and back button
self.row[2].pack(fill=X)
def initWidgets(self):
# create the rows or groups of widgets
for i in range(3):
self.row.append(Frame())
# row 0; startWindow
self.size_entry = Entry(self.row[0])
self.size_entry.pack(fill=X, side=LEFT)
self.size_button = Button(self.row[0], text="Enter", command=lambda:self.generateBoard([0]))
self.size_button.pack(fill=X, side=LEFT)
self.load_button = Button(self.row[0], text="Load", command=self.loadFile)
self.load_button.pack(fill=X, side=LEFT)
# row 2; generateBoard
self.solve_button = Button(self.row[2], text="Solve", command=self.showSolutions)
self.solve_button.pack(fill=X, side=LEFT)
self.back_button = Button(self.row[2], text="Back", command=lambda:self.startWindow(to_forget=[0,2], to_destroy=[1]))
self.back_button.pack(fill=X, side=RIGHT)
def loadFile(self):
print("file loaded!")
def place(self, i, j):
if self.board_strvars[i][j].get() == " ":
self.board_strvars[i][j].set("C")
else:
self.board_strvars[i][j].set(" ")
def showSolutions(self):
print("solutions shown!")
def startWindow(self, to_forget=None, to_destroy=None):
# hides the groups of the method that called it
if to_forget != None:
for i in to_forget:
self.row[i].forget()
# destroys the groups' child widgets and hides the group
if to_destroy != None:
for i in to_destroy:
for child in self.row[i].winfo_children():
child.destroy()
self.row[i].forget()
self.row[0].pack(fill=X)
if __name__ == "__main__":
root=Tk()
root.title("test")
app = MainWindow(root)
root.mainloop()
Я изначально хотелопределить функцию, которая изменит text
из button
, который ее вызвал.Но до сих пор я не нашел способа сделать это.
Использование решений, предложенных в посте, который я связал, ничего не меняет в кнопках.Однако в приведенном мною коде я использовал StringVar()
, который был назначен как textvariable
из button
.Однако он изменяет только последний ряд, последний элемент кнопки столбца, независимо от того, какую кнопку вы нажимаете.Он должен работать так, чтобы кнопка, которая была нажата, изменила свой текст.
Спасибо!