参考按钮然后配置它

时间:2012-10-02 16:06:28

标签: python button tkinter

好吧,我遇到的问题是我不明白如何引用按下的特定按钮。我正在做一个游戏,如果使用点击一个按钮我想知道它有哪个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"

3 个答案:

答案 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()