2010-05-28 3 views
4

여기에 들어가는 문제는 Listbox에서 다른 파일 이름을 클릭하면 Label은 현재 클릭하고있는 값보다 한 번의 클릭을 변경합니다. 에.Tkinter StringVar에 바인딩 된 레이블이 한 번의 클릭으로 업데이트 될 때

무엇이 여기에 있습니까?

import Tkinter as tk 

class TkTest: 

    def __init__(self, master): 

     self.fraMain = tk.Frame(master) 
     self.fraMain.pack() 

     # Set up a list box containing all the paths to choose from 
     self.lstPaths = tk.Listbox(self.fraMain) 
     paths = [ 
      '/path/file1', 
      '/path/file2', 
      '/path/file3', 
     ] 
     for path in paths: 
      self.lstPaths.insert(tk.END, path) 
     self.lstPaths.bind('<Button-1>', self.update_label) 
     self.lstPaths.pack() 

     self.currentpath = tk.StringVar() 
     self.lblCurrentPath = tk.Label(self.fraMain, textvariable=self.currentpath) 
     self.lblCurrentPath.pack() 

    def update_label(self, event): 
     print self.lstPaths.get(tk.ACTIVE), 
     print self.lstPaths.curselection() 
     self.currentpath.set(self.lstPaths.get(tk.ACTIVE)) 

root = tk.Tk() 
app = TkTest(root) 
root.mainloop() 

답변

4

문제는 Tk의 기본 설계와 관련이 있습니다. 짧은 버전은 특정 위젯의 바인딩이 위젯의 ​​기본 클래스 바인딩 이전에 실행된다는 것입니다. 클래스 바인딩에서 목록 상자의 선택이 변경됩니다. 이것은 정확히 당신이 관찰하는 것입니다 - 현재 클릭 전에 선택을보고 있습니다.

최상의 해결 방법은 선택이 변경된 후 실행되는 가상 이벤트 <<ListboxSelect>>에 바인딩하는 것입니다. Tk만의 독창적 인 솔루션과 그 강력한 기능과 유연성을 제공하는 다른 솔루션은 바인딩이 적용되는 순서를 수정하는 것입니다. 여기에는 클래스 bindtag 다음에 위젯 bindtag를 이동하거나 클래스 bindtag 다음에 새 bindtag를 추가하고이를 바인딩합니다.

<<ListboxSelect>>에 대한 바인딩이 더 나은 솔루션이므로 bindtags를 수정하는 방법에 대한 세부 사항은 다루지 않을 것입니다. 물론 간단하고 명료하게 문서화되어 있습니다.

+0

그 트릭을 했어, 고마워! << ListboxSelect >>에 대한 참조는 어디서나 내가 겪어 온 튜토리얼에서 보지 못했고 정확한 단어에 대한 인터넷 검색도 많은 정보를 제공하지 않는 것 같습니다. 모든 가상 이벤트의 목록이 있습니까? 이것은 Tk에서 성가신 '잡아 당김'처럼 보입니다. – Sam

+1

@Sam : 모든 이벤트의 단일 목록이 없습니다. Tk 맨 페이지는 해당 위젯의 맨 페이지에있는 각 위젯에 대한 이벤트를 나열합니다. 예를 들어, << ListboxSelect >>는 목록 상자 맨 페이지에 있습니다. http://tcl.tk/man/tcl8.4/TkCmd/listbox.htm –