2012-12-20 2 views
3

아래 코드에서 self.dmenu1.bind("<Button-1>", self.branches) 행에 문제가 있습니다. 누군가 올바른 방향으로 설정해 주실 수 있으면 정말 고맙겠습니다.Python TKinter 드롭 다운 메뉴 문제

드롭 다운 메뉴에서 옵션을 선택하면 그 아래의 목록 상자에서 정렬이 변경됩니다.
그러나 실제로 일어나고있는 일은 선택을 한 후에 드롭 다운 상자를 한 번 더 클릭해야만 정렬이 적용됩니다.

사용자가 드롭 다운 메뉴를 사용할 것으로 기대하는 방식이 아닙니다. 내가 완전히 익숙하다는 것을 알 수 있듯이, 전체 코드를 게시했지만, 배울 좋은 도전 과제입니다.

미리 도움을 청하십시오.
감사

from tkinter import * 

ALL = N+S+W+E 

users = ['Fred Asus','Tom Yahoo','Jessy Samsung','Jermain Sony','Nikki Nikon', 
     'Ian IBM','Elena Google','Rob Braun','Tammy Tonika','James Intel', 
     'Murphy Richards','Daniel Denon'] 

branchlst = {138:'Driving - St Albans', 170:'Brighton', 271:'Driving - Birmingham', 
      330:'Leeds', 680:'Edinburgh'} 

class Application(Frame): 

    def __init__(self, master=None): 
     #initiate the primary window. 
     Frame.__init__(self, master) 
     self.master.rowconfigure(0, weight=1) 
     self.master.columnconfigure(0, weight=1) 

     self.rowconfigure(0, weight=0) 
     self.rowconfigure(1, weight=0) 
     self.rowconfigure(2, weight=3) 
     self.columnconfigure(0, weight=0) 
     self.columnconfigure(1, weight=1) 
     self.columnconfigure(2, weight=1) 

     self.grid(sticky=ALL) 
     self.frameset() 

    def frameset(self): 
     #define and setup frames with columns and rows for widgets 
     #Colours added to framesets to help designing layout. delete them 
     self.Frame1 = Frame(self) # D 
     self.Frame2 = Frame(self, bg='blue') # E 
     self.Frame3 = Frame(self)    # L 
     self.Frame4 = Frame(self, bg='blue') # E 
     self.Frame5 = Frame(self) # T 
     self.Frame6 = Frame(self) # E colours 

     self.Frame1.rowconfigure(0,weight=0) 
     self.Frame2.rowconfigure(0,weight=0) 
     self.Frame3.rowconfigure(0,weight=1) 
     self.Frame4.rowconfigure(0,weight=1) 
     self.Frame5.rowconfigure(0,weight=1) 
     self.Frame6.rowconfigure(0,weight=1) 

     self.Frame1.columnconfigure(0,weight=0) 
     self.Frame2.columnconfigure(0,weight=0) 
     self.Frame3.columnconfigure(0,weight=1) 
     self.Frame4.columnconfigure(0,weight=1) 
     self.Frame5.columnconfigure(0,weight=1) 
     self.Frame6.columnconfigure(0,weight=1) 

     self.Frame1.grid(row=0, column=0, rowspan=1, columnspan=1, sticky=ALL) 
     self.Frame2.grid(row=0, column=1, columnspan=2, sticky=ALL) 
     self.Frame3.grid(row=1, column=0, rowspan=2, sticky=ALL) 
     self.Frame4.grid(row=1, column=1, columnspan=2, sticky=ALL) 
     self.Frame5.grid(row=2, column=1, rowspan=1, columnspan=1, sticky=ALL) 
     self.Frame6.grid(row=2, column=2, sticky=ALL) 


     label4a = Label(self.Frame4, text='table1', bg='orange') 
     label4b = Label(self.Frame4, text='table2', bg='yellow') 
     label4a.pack(side=LEFT) 
     label4b.pack(side=RIGHT) 

     self.objects() 

    def objects(self): 
     var = StringVar() 
     var.set('Name') 
     self.dmenu1 = OptionMenu(self.Frame1, var,'Costcode','Name') 
     self.dmenu1.pack(side=TOP, fill=BOTH) 
     self.dmenu1.bind("<Button-1>", self.branches) 

     self.f3ListBox = Listbox(self.Frame3, selectmode='single') 
     #self.branches() 
     self.f3ListBox.grid(sticky=ALL) 
     self.f3ListBox.bind("<Button-3>", self.f1handler1) 

     f5ListBox = Listbox(self.Frame5, selectmode='single') 
     n = 0 
     for item in users: 
      f5ListBox.insert(n,item) 
      n += 1 
     f5ListBox.grid(sticky=ALL) 

     f6ListBox = Listbox(self.Frame6, selectmode='single') 
     f6ListBox.insert(1,'S123456') # DELETE 
     f6ListBox.insert(2,'S313414') # DELETE 
     f6ListBox.insert(3,'S573343') # DELETE 
     f6ListBox.grid(sticky=ALL)  


    def f1handler1(self, event): 
     """Creates a popup menu for the alternative mouse button. 
     Edit this to add more options to that popup""" 
     select = lambda: self.f3ListBox.delete(ACTIVE) 
     popup = Menu(self, tearoff=0) 
     popup.add_command(label='Quit',command=self.quit) 
     popup.add_command(label='delete',command=select) #add more of these for more options 


     try: 
      popup.post(event.x_root, event.y_root) 
     except: 
      pass 
    def branches(self, event): 
     self.f3ListBox.delete(0,END) 
     n = 0 
     if self.dmenu1.cget('text') == 'Costcode': 
      cc = sorted(list(branchlst.keys())) 
      for item in cc: 
       self.f3ListBox.insert(n,str(item)+' '+branchlst[item]) 
       n += 1 
     elif self.dmenu1.cget('text') == 'Name': 
      bb = sorted(list(branchlst.values())) 
      for item in bb: 
       for name,val in branchlst.items(): 
        if item == val: 
         self.f3ListBox.insert(n,item+' '+str(name)) 

root = Tk() 
app = Application(master=root) 
app.mainloop() 

답변

5

나는이 문제를 이해하고 해결하는 길을 선호한다. 그래서 우리는 그것을 살펴 보자. 귀하의 코드에는 self.dmenu1.bind("<Button-1>", self.branches)이 있습니다.

이 이벤트는 실제로 언제 해고 되었습니까? OptionMenu을 클릭하면 해고됩니다. 즉, 현재 옵션이 사용됩니다. 따라서 "a"옵션이 활성화되어 있고 "b"옵션으로 변경했다고 가정합니다. 이 선택 변경은 Button-1 이벤트를 발생시키지 않지만, OptionMenu을 다시 클릭하면 실행되고 위젯은 현재 옵션으로 "b"를 갖습니다.

실제로 코드에서 무엇 :

self.dmenu1 = OptionMenu(self.Frame1, var,'Costcode','Name', 
         command=self.branches) 

및 언급 된 바인딩을 안전하게 제거 할 수있다 이전. 추가 된 command 옵션은 OptionMenu에서 선택 될 때마다 특정 기능을 호출합니다. 이 변경 외에도 프로그램 시작시 목록 상자를 채울 수도 있습니다. 이를 위해서는 self.f3ListBox을 정의한 후에 self.branches(None)으로 전화하십시오.

+0

감사합니다. 내 이해로 큰 도움이되었습니다. 나는 바인딩이 필요하다는 인상 아래 있었고, 당신이 친절하게도 내가 궁금해했던 또 다른 질문 인 self.branches (None)에 대답했다. 아무도 여기에서 일하지 않는다는 것을 깨닫지 못했다. 많은 감사, 교훈 : – Zenettii

+0

바인딩이 필요한 다른 장소/상황이 있지만 이번에는 없습니다. Tkinter 개발을 계속하면 다음과 같은 다른 상황을 발견 할 수 있습니다 :) – mmgp

2

StringVar 클래스는 당신이 그것에 콜백 함수를 첨부 할 수있는 trace 방법을 가지고 있습니다. 변수가 값을 변경하면 함수가 호출됩니다.

코드에 objects 메서드의 var.set('Name') 줄 바로 아래에이 줄을 추가하십시오.

var.trace('w', self.branches) 

self.branches이 때마다 var 변경 호출하게됩니다. 당신은 또한 self.dmenu1.bind("<Button-1>", self.branches) 라인을 삭제해야

def branches(self, name, index, mode): 

지금 중복으로 : 당신이 가지 '정의를 변경해야합니다, 그래서 그것은 세 개의 인수로 호출됩니다.

+0

Kevin, 귀하의 회신은 실제로 구현 될 때 멋지게 작동하며, 이제 var.trace 메서드를 발견했습니다. 감사합니다. @ mmgp가 지금 나와 저의 이해 수준에 더 적합한 답변을 제공했다고 느꼈습니다. 당신의 답변에 감사드립니다. 대단히 감사하고 유익한. – Zenettii

+0

@Zenettii 여기에 무료 팁이 있습니다. 가능한 한 많이 파이썬에 충실하십시오. 이것이 의미하는 바는,이 변수 추적은 파이썬이 아니라 Tcl에 의해 실제로 수행된다는 것입니다. Python과 Tcl 사이의 다리는 두 언어 간의 근본적인 차이로 인해 데이터 유형에 대한 모든 종류의 놀라움을 제공합니다.파이썬에서 Tkinter를 사용하는 동안 Tcl 변수를 벗어나기 위해 처리 할 수 ​​있다면 그렇게하십시오. – mmgp