2012-10-02 46 views
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" 
+0

你能解釋你想用'command = lambda i = i + 20:function(i) '?我不認爲這是有效的Python語法。 – Kevin

+1

這似乎是部分僞代碼。這是你實際寫的嗎? – Tadgh

+0

@Kevin:這是非常好的Python代碼,你爲什麼認爲這是錯的?無可否認,它可能會寫得更清晰一些,比如'lambda widget_number = i + 20:function(widget_number)',但無論哪種方式都有效。 –

回答

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得到相同的結果,如果你發現拉姆達很難繞到你的頭:

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] 
+0

你給的最後一個例子正是我所需要的! – Entalpi

-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() 
+0

多數民衆贊成真棒!問題是我不知道如何判斷哪個按鈕被點擊。我只想要一些按鈕變成紅色,如「如果e.widget的x = 4和y = 3」。謝謝你回答btw! – Entalpi

+0

@Entalpi:如果這不符合你的要求,爲什麼接受它? –

+0

那麼,根據我的解釋,它解決了他最初的問題。這就是爲了解釋:「當用戶點擊一個按鈕時,改變該按鈕的顏色」。我會添加一些細節來解決他修改後的要求。 – Kevin

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): 
     ... 

立即清楚您創建五行五列,而用您的原始代碼需要幾秒鐘的研究才能得出相同的結論。

+0

我這樣做,讓每個按鈕獲得我個人的價值,然後與他們分開。但我仍然認爲它的代碼太多太簡單了。感謝您的答案btw! – Entalpi

相關問題