2013-01-22 2 views
0

python/tkinter에서 작동하도록 이벤트 바인딩을 가져 오는 데 문제가 있습니다. 나는 단순히 클릭하여 위치 인쇄를하려고하지만, 이렇게 할 때마다 "-1"이 결과입니다.python tkinter 목록 상자 이벤트 바인딩

여기에 내 코드

from Tkinter import * 
import Tkinter 

class make_list(Tkinter.Listbox): 

    def __init__(self,master, **kw): 
     frame = Frame(master) 
     frame.pack() 
     self.build_main_window(frame) 

     kw['selectmode'] = Tkinter.SINGLE 
     Tkinter.Listbox.__init__(self, master, kw) 
     master.bind('<Button-1>', self.click_button) 
     master.curIndex = None 

    #display the clicked location 
    def click_button(self, event): 
     self.curIndex = self.nearest(event.x) 
     print self.curIndex 

    #display the window, calls the listbox 
    def build_main_window(self, frame): 
     self.build_listbox(frame) 

    #listbox 
    def build_listbox(self, frame): 
     listbox = Listbox(frame) 
     for item in ["one", "two", "three", "four"]: 
      listbox.insert(END, item)  
     listbox.insert(END, "a list entry") 
     listbox.pack() 
     return 

if __name__ == '__main__': 
    tk = Tkinter.Tk() 
    make_list(tk) 
    tk.mainloop() 

업데이트 된 코드 - I 프레임을 제거있어하지만 난 함수 click_button에서 첫 번째 인쇄 문 -1납니다 이유를 알아낼 수 없습니다

from Tkinter import * 
import Tkinter 

class make_list(Tkinter.Listbox): 

    #display the clicked location 
    def click_button(self, event): 
     ##this block works 
     w = event.widget 
     index = int(w.curselection()[0]) 
     value = w.get(index) 
     print value 
     ##this doesn't 
     self.curIndex = self.nearest(event.y) 
     print self.curIndex 
     self.curIndex = event.widget.nearest(event.y) 
     print self.curIndex 

    #display the window, calls the listbox 
    def build_main_window(self): 
     self.build_listbox() 

    #listbox 
    def build_listbox(self): 
     listbox = Listbox() 
     listbox.bind('<<ListboxSelect>>', self.click_button) 
     for item in ["one", "two", "three", "four"]: 
      listbox.insert(END, item)  
     listbox.insert(END, "a list entry") 
     listbox.pack() 
     return 

if __name__ == '__main__': 
    tk = Tkinter.Tk() 
    start = make_list(tk) 
    start.build_main_window() 
    start.mainloop() 
+1

"위치"란 무엇을 의미합니까? 항목의 색인, x/y 좌표 또는 현재 선택된 데이터를 원하십니까? –

답변

1

listbox 가까운 항목은 y하지 x에 의해 발견된다.

self.nearest(event.x)  # wrong 
self.nearest(event.y)  # right 

업데이트 : 내가 먼저 진짜 문제를 발견하지 않았다 : 그것은 당신이 서브 클래스 같은 목록 상자 아니다

listbox = Listbox(frame) 

, 그것은 또 다른 관련이없는 목록 상자입니다. 목록 상자 ( make_list 임)는 비어 있으므로 가장 가까운 경우 항상 -1을 반환합니다. 아마도 프레임의 서브 클래스

좋은 생각이다 (어쨌든, 목록 상자를 서브 클래 싱하고 그것으로 다른리스트 박스와 프레임을 추가하는 것보다 더 나은). 그럼 당신은 그 이벤트에 바인드해야합니다 목록 상자가 비어 있지 않습니다.

빠른 방법은 일 고정 된 것이 event.widget와 실제 목록 상자의 nearest를 호출하는 방식을 볼 수 있습니다 :

self.curIndex = event.widget.nearest(event.y) 
+0

은 curIndex (click_button 메서드에서)를 인쇄 할 때 여전히 -1을 표시합니다. – user1104854

+0

@ user1104854가 하나 더 문제를 설명했습니다. –

+0

코드를 추가하면 올바른 위치가 표시됩니다. Consdiering 나는 아직도 이것에 대해 아주 새로운 것으로 확신한다. 나는 이것을 알아낼 수있을 것이라고 확신한다. 그러나이 상황을위한 최선의 방법을 알고 싶다. 그래서 나는 장황한 코드에서 미래에 문제가 생기지 않도록한다. 당신이 바꿀 것에 대해 조언을 좀 해줄 수 있니? – user1104854

6

당신이 가장 좋은 방법에 대한 질문에 대한 답변의 의견에. 가장 좋은 방법은 목록 상자에서 항목을 선택한 직후에 실행되는 <<ListboxSelect>>에 바인딩하는 것입니다.

This answer 비슷한 질문에 대한 예가 있습니다.

+0

위 편집을 업데이트했습니다. 나는 당신이 제안한 것을 시도했다. 그러나 출력으로 0을 얻고있다. – user1104854

+0

@ user1104854 : 두 가지 문제가 있습니다. 하나는 self.nearest()를 요청한다는 것입니다. 그러나 self는 데이터가있는 위젯이 아니며 클릭하는 위젯이 아닙니다. 목록 상자에 목록 상자가 포함 된 매우 이상한 코드가 있습니다. 또한, 나는''ListboxSelect >>'가'event.x'와'event.y'를 설정한다고 생각하지 않습니다. 이벤트는 클릭을 나타내지 않고 이벤트는 "현재 항목이 변경되었습니다."를 나타내며 x 및 y를 항상 가질 수는 없습니다 (예 : 키보드를 사용하여 현재 선택 항목을 변경하는 경우). 'event.widget.curselection()'을 사용해야합니다. –