如何更改嵌套列表中每个按钮的文本?

时间:2019-05-09 13:01:24

标签: python python-3.x tkinter

我已经查看了SO并尝试了提供的解决方案,但是我似乎无法更改使用双text循环创建的任何button的{​​{1}}。

这里有循环,因此我可以将它们添加到for的{​​{1}}中的list中,这样我就可以(应该)通过调用{{1}通过嵌套列表方便地访问它们} 或者其他的东西。在用户输入lists之后,也会动态创建它们,从而生成nxn个按钮的网格,这样就可以了。这些都是在类方法内完成的,还有另一个类方法应在通过按钮调用buttons的{​​{1}}时对其进行更改。

我曾尝试使用here提供的解决方案,但实际上没有一个解决我的问题。

请原谅很长的代码段,但是老实说,我认为编写代码的方式可能导致了问题,并提供了更多的见解。

board_button[2][3]

最初,我想定义一个函数来更改调用它的board_size中的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。但是,无论您单击哪个按钮,它都只会更改最后一行,最后一列按钮元素。应该以一种方式工作,即单击的按钮将更改其文本。

谢谢!

1 个答案:

答案 0 :(得分:1)

更改您的lambda函数以强制关闭:

def generateBoard(self, to_forget=None):
    ...

    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 i=i, j=j:self.place(i, j)))
            self.row_buttons[j].grid(row=i, column=j)

        self.board_buttons.append(self.row_buttons)

还要注意,最好不要调用自己的方法place,因为Tk中已经有一个place方法。