好吧,我遇到的问题是我不明白如何引用按下的特定按钮。我正在做一个游戏,如果使用点击一个按钮我想知道它有哪个X和Y坐标。所以,如果你有一个按钮网格,你单击一个我想要坐标,然后我将改变该按钮的颜色。 :)
问题:知道在网格中按下了哪个按钮。
提前致谢!
def matris():
for i in range(5):
newButton = Button(app, width = 4, height = 2, bg = "blue",command = lambda i=i: function(i))
newButton.grid(row = i, column = 0)
for i in range(5):
newButton = Button(app, width = 4, height = 2, bg = "blue",command = lambda i=i + 5: function(i))
newButton.grid(row = i, column = 1)
for i in range(5):
newButton = Button(app, width = 4, height = 2, bg = "blue",command = lambda i=i + 10: function(i))
newButton.grid(row = i, column = 2)
for i in range(5):
newButton = Button(app, width = 4, height = 2, bg = "blue",command = lambda i=i + 15: function(i))
newButton.grid(row = i, column = 3)
for i in range(5):
newButton = Button(app, width = 4, height = 2, bg = "blue",command = lambda i=i + 20: function(i))
newButton.grid(row = i, column = 4)
def function(i):
if button 23 was clicked.changeColor to e.g "blue"
答案 0 :(得分:1)
阅读完所有评论和编辑后,看起来你真正想知道的是“点击了哪个按钮?”当为多个按钮使用相同的命令时。
最简单的方法是将某种唯一标识符传递给与窗口小部件关联的命令。最直接的方法是传递对窗口小部件本身的引用,但这需要两个步骤。
例如:
this_button = Button(...)
this_button.configure(command=lambda button=this_button: do_something(button))
def do_something(button):
print "you clicked this button:", button
如果你发现lambda很难缠绕,你也可以使用functools.partial
得到相同的结果:
this_button.configure(command=functools.partial(do_something, this_button)
如果您希望在一步而不是两步中创建按钮,则需要一些方法来识别它。对我来说,最简单的方法是使用字典。例如,如果要创建按钮的行和列,则可以执行以下操作:
button = {}
for r in range(10):
for c in range(10):
button[r,c] = Button(..., command=lambda row=r, column=c: do_something(row, ccolumn))
def do_something(row, column):
print "you clicked button", button[row,column]
答案 1 :(得分:0)
如果您想稍后修改该按钮,则需要保留对每个按钮的引用。由于您的编号方案是连续的,您可以使用列表:
newButton = Button(...)
buttons.append(newButton)
...
def function(i):
widget = buttons[i-1] # -1, because list indexes are zero-based
if i == 23:
widget.configure(background="blue")
如果您正在创建按钮网格并且按钮在其他方面完全相同,您可能需要考虑更简单的结构,例如:
for row in range(5):
for column in range(5):
...
立即清楚你要创建五行五列,而使用原始代码需要几秒钟的研究才能得出相同的结论。
答案 2 :(得分:-1)
使用command
方法设置bind
的回调,而不是使用<Button-1>
参数。当Tkinter调用你的回调时,它会传入一个事件对象,其中包含引发事件的小部件。
from Tkinter import *
def buttonClicked(e):
e.widget["bg"] = "red"
root = Tk()
for x in range(5):
for y in range(5):
newButton = Button(root, width=10, height=2, bg="blue")
newButton.bind("<Button-1>", buttonClicked)
newButton.grid(row=y, column=x)
root.mainloop()
编辑:假设你想根据它们在网格中的位置来区别对待按钮。最简单的方法是使用全局字典将每个按钮与其坐标相关联。
from Tkinter import *
coords = {}
def buttonClicked(e):
x,y = coords[e.widget]
print "{},{} clicked".format(x,y)
if x == 4 and y == 3:
e.widget["bg"] = "red"
root = Tk()
for x in range(5):
for y in range(5):
newButton = Button(root, width=10, height=2, bg="blue")
newButton.bind("<Button-1>", buttonClicked)
newButton.grid(row=y, column=x)
coords[newButton] = (x,y)
root.mainloop()
但是,一般而言,在全局范围内使用变量并不是一个好主意。将所有基于网格的代码分组到一个类中可能是值得的,因此没有任何细节泄漏到程序的其余部分。
from Tkinter import *
class ButtonGrid:
def __init__(self, root):
self.coords = {}
for x in range(5):
for y in range(5):
newButton = Button(root, width=10, height=2, bg="blue")
newButton.bind("<Button-1>", self.buttonClicked)
newButton.grid(row=y, column=x)
self.coords[newButton] = (x,y)
def buttonClicked(self, e):
x,y = self.coords[e.widget]
print "{},{} clicked".format(x,y)
if x == 4 and y == 3:
e.widget["bg"] = "red"
root = Tk()
b = ButtonGrid(root)
root.mainloop()
如果您更喜欢功能而不是面向对象,那么这是另一种选择。像在原始代码中一样使用command
选项,但使用functools.partial
函数提前指定哪些变量应该传递给函数。
from Tkinter import *
import functools
def buttonClicked(widget, x, y):
print "{},{} clicked".format(x,y)
if x == 4 and y == 3:
widget["bg"] = "red"
root = Tk()
for x in range(5):
for y in range(5):
newButton = Button(root, width=10, height=2, bg="blue")
newButton["command"] = functools.partial(buttonClicked, newButton, x, y)
newButton.grid(row=y, column=x)
root.mainloop()