2013-04-25 2 views
6

ive가 해결책을 찾으려고했지만 작동하는 해결책을 찾지 못했습니다. 두 번째 tkinter Buttons 목록이 있는데 마우스로 클릭하면 해당 텍스트가 변경됩니다. 나는이 일을 시도 :파이썬에서 lambda를 사용하는 tkinter 버튼 명령

def create_board(number): 
    print(number) 
    for i in range (0,number): 
     buttonList.append([]) 
     for j in range(0,number): 
      print(i,j) 
      buttonList[i].append(Button(root, text = " ", command = lambda: update_binary_text(i,j))) 
      buttonList[i][j].pack() 

을 그리고 그것을 클릭 할 때 호출이 기능 : 내가 버튼을 클릭하면, 단순히 아무것도하지 않는

def update_binary_text(first,second): 
    print(first,second) 
    buttonList[first][second]["text"] = "1" 

, 내가 가진 프로그램이 버튼의 인덱스를 표시를 그걸 클릭했고, 그들은 모두 4, 4를 표시합니다 (이것은 변수 수 = 5 일 때입니다) 해결책이 있습니까?
이 클래스에 대한 첫 번째 파이썬 시도입니다.

감사

당신은 각 람다의 창조와 ij에 대한 폐쇄를 만들어이 문제를 해결할 수

답변

8

: 버튼은 개체 자체에

command = lambda i=i, j=j: update_binary_text(i, j) 

또한 참조가 콜백 공장을 만들 수 있습니다 :

def callback_factory(button): 
    return lambda: button["text"] = "1" 

와 다음 초기화 코드 :

for j in range(0, number): 
    new_button = Button(root, text=" ") 
    new_button.configure(command=callback_factory(new_button)) 
    new_button.pack() 
    buttonList.append(new_button) 
+0

와우! 당신의 솔루션은 효과가있었습니다! 감사합니다! 지금은 게시 한 첫 번째 예제를 고수했습니다. 그러나 나는 당신이 보여준 두 번째 예를 확실히 공부할 것입니다. 다시 한 번 감사드립니다! – vap

0

비슷한 위젯 모음이 필요할 때마다 객체에서 그들을 묶고 람다로 트릭을하기보다는 콜백으로 바인딩 메소드를 전달하는 것이 가장 간단하다는 것을 알았습니다. 그래서, 대신 위젯 buttonList[] 같은 목록이 필요없이 객체를 생성 :

class MyButton(object): 
    def __init__(self, i, j): 
     self.i = i 
     self.j = j 
     self.button = Button(..., command = self.callback) 

    def callback(self): 
     . . . 

지금, 당신은 오히려 위젯 자체보다, 이러한 개체의 목록 buttonList[] 있습니다. 텍스트를 업데이트하려면 해당 메서드를 제공하거나 회원에게 직접 액세스하십시오. buttonList[i].button.configure(. . .) 콜백이 활성화되면 전체 개체와 필요한 특성이 모두 self에 있습니다.