0

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

3 回答 3

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

functools.partial如果您发现 lambda 难以理解,您也可以使用它来获得相同的结果:

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]
于 2012-10-10T21:12:29.343 回答
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):
        ...

很明显,您正在创建五行五列,而使用您的原始代码需要几秒钟的研究才能得出相同的结论。

于 2012-10-02T19:27:30.607 回答
-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()
于 2012-10-02T16:34:58.220 回答