我正在尝试将我在python中编写的代码改编为使用tkinter的程序。 我为董事会中的每个字符(X和O)列出了一个列表,并列出了一个按钮列表。每个按钮在按下时应根据情况从“”更新为“ X”或“ O”。其余代码尚未完成,但这并不是问题所在。
我使用marcar(i,j,texto)
作为更新按钮文本的功能,以按钮列表中按钮的位置为参考。但在第25行中,显示“列表索引超出范围”的错误。我在第31行中使用了相同的命令。我想这是因为在创建按钮的第29行中,用于创建按钮的事情之一是方法marcar()
,因为它尚未被使用。在列表中创建了其他任何对象,我无法引用它。
我找不到任何制作按钮的解决方案,当按下按钮时,它会使用引用同一按钮的方法,因为要创建该按钮,我需要功能。
from tkinter import *
lista = [[" ", " ", " "],
[" ", " ", " "],
[" ", " ", " "]]
buttons = [[], [], []]
vitx = 0
vito = 0
root = Tk()
turno = Label(root, text="Turno de X",font=("Arial",15))
turno.grid(row = 1,column = 1)
vitoriasx = Label(root, text="Vitórias de X:"+str(vitx), font=("Arial",8))
vitoriasx.grid(row = 1,column = 0)
vitoriaso = Label(root, text="Vitórias de O:"+str(vito), font=("Arial",8))
vitoriaso.grid(row = 1,column = 2)
def marcar(i,j,texto):
lista[i][j] = texto
buttons[i][j].config(text= texto)
for i in range(0,3):
for j in range(0,3):
buttons[i].append(Button(root,text=lista[i][j],command = marcar(i,j,"x")))
buttons[i][j].grid(row = i+2,column = j)
buttons[i][j].config(height=6, width=13)
root.mainloop()
答案 0 :(得分:1)
您需要为这组循环构建适当的lambda函数,以使按钮将正确的信息发送给函数,而又不会导致命令在初始化时执行。
在python中,当您需要保存对函数的引用时,有2个选项。
对于不带参数的函数,您可以省略括号()
来保存对该函数的引用,或者如果需要传递参数,则可以使用lambda表达式。
如果您确实使用了lambda表达式,并且像在此处那样在循环中更改了变量,则需要定义每个循环中每个参数的含义,否则这些值将等于最后一个循环的值。
例如,如果您简单地使用lambda而不在每个循环中定义变量,那么最终将得到所有都发送相同数据的按钮。
这里是一个例子:
import tkinter as tk
root = tk.Tk()
def marcar(i, j, texto):
print(i, j, texto)
for i in range(0, 3):
for j in range(0, 3):
tk.Button(root, text='button {}.{}'.format(i, j), command=lambda: marcar(i, j, "x")).grid(row=i, column=j)
root.mainloop()
结果:
但是,如果您在每个循环的lambda中定义值,则每个按钮将获得正确的值。
示例:
import tkinter as tk
root = tk.Tk()
def marcar(i, j, texto):
print(i, j, texto)
for i in range(0, 3):
for j in range(0, 3):
tk.Button(root, text='button {}.{}'.format(i, j), command=lambda i=i, j=j: marcar(i, j, "x")).grid(row=i, column=j)
root.mainloop()
结果:
答案 1 :(得分:0)
问题是您不能像这样在var img: HTMLImageElement;
function showImageFile( file: File ): void {
let oldSrc = img.src;
let objectURI = URL.createObjectURL( file );
img.src = objectURI;
if( oldSrc ) URL.revokeObjectURL( oldSrc );
}
中传递参数。您必须将command
更改为command=marcar(i,j,"x")
。您可以找到here和here的说明。尝试以下代码:
command=lambda: marcar(i, j, "x")