2014-02-09 2 views
0

글쎄, 내 첫 번째 파이썬/Tkinter 프로젝트에 1000 라인입니다. 몇 마디로 날 길을 가야 할 시간이야. 그래서 처음에는 레이아웃 표시 버튼을 비활성화 (회색으로 표시)하고 싶습니다. 파일이로드 된 후 디스플레이 레이아웃이 활성화됩니다.파이썬 Tkinter 형제 상호 작용 윈도우

def ReadFile() 
    #Something Magical Happens 
    Layoutbutton.config(state='active') 

def DisplayLayout() 
    #Draw Great gobs of stuff 

def main() 
    global Layoutbutton 
    #setup root window yada yada yada 
    Layoutbutton=Button(root,text="Layout",command=DisplayLayout,underline=0) 
    Layoutbutton.place(relx=.5,rely=.85,anchor=CENTER) 
    root.bind("l",DisplayLayout) 
    root.bind('L',DisplayLayout) 
    Layoutbutton.config(state='disabled') 

    BrowesButton=Button(root,text="File",command=ReadFile,underline=0) 
    BrowesButton.place(relx=.75,rely=.85,anchor=CENTER) 
    root.bind("F",ReadFile) 
    root.bind('f',ReadFile) 

if __name__ == '__main__': 

    root=Tk() 
    main() 

이 모두가 예상대로 작동합니다. 파일을 읽을 때까지 DisplayLayout 단추가 gery됩니다.

나는 글로벌 LayoutButton의 사용에 의문을 제기하고 있습니다. 나는 이런 종류의 일이 계속 일어나고 있습니다. (더 나은 용어가 부족하여) 형제 창은 너무 많은 전역 변수없이 서로 통신합니까?

답변

0

코드를 객체화하여 전역을 사용할 수 있습니다. 이것은 개인적인 취향

def read_file(): 
    #magic happens  

class MyFrame(object): 
    def __init__(self,parent): 
     self.parent = parent 
     self.layout_button = Button(self.parent,text="Layout", 
          command=self.display_layout,underline=0) 
     self.layout_button.place(relx=.5,rely=.85,anchor=CENTER) 
     self.parent.bind("l",self.display_layout) 
     self.parent.bind('L',self.display_layout) 
     self.layout_button.config(state='disabled') 
     self.browes_button=Button(self.parent,text="File", 
            command=self._call_read_file,underline=0) 
     self.browes_button.place(relx=.75,rely=.85,anchor=CENTER) 
     self.parent.bind("F",self._call_read_file) 
     self.parent.bind('f',self._call_read_file) 

    def display_layout(self): 
     #populate frame etc. 

    def _call_read_file(self): 
     read_file() 
     self.layout_button.config(state='active') 

def main(root): 
    frame = MyFrame(root) 
    root.mainloop() 

if __name__ == "__main__": 
    root = Tk() 
    main(root)  

수 있지만,이 같은 훨씬 더 직관적 인 설계 GUI를 발견하고 무거운하게 코드에 비해 원치 않는 행동을 추적하기 쉽게 예를 들어 귀하의 예제의 다른 구현 될 수있다 전역의 사용. 이 방법으로 모든 프레임은 부모 프레임에 대한 참조를 유지하므로 업데이트를해야 할 경우 모든 프레임에 서로 액세스 할 수 있어야합니다. 완전하고 오히려 어리석은 예제는 다음과 같습니다.

import Tkinter as tk 

class MyOtherFrame(object): 
    def __init__(self,parent): 
     self.root = parent 
     self.enable_button = tk.Button(self.root,text="enable",command=self.enable) 
     self.enable_button.pack() 
     self.disable_button = tk.Button(self.root,text="disable",command=self.disable) 
     self.disable_button.pack() 
     self.child_frame = tk.Frame(self.root) 
     self.child_frame.pack() 
     self.child_frame_obj = MyFrame(self.child_frame) 

    def enable(self): 
     self.child_frame_obj.button.config(state="active") 

    def disable(self): 
     self.child_frame_obj.button.config(state="disabled") 

class MyFrame(object): 
    def __init__(self,parent): 
     self.root = parent 
     self.button = tk.Button(self.root,text="useless button") 
     self.button.pack() 

def main(): 
    root = tk.Tk() 
    x = MyOtherFrame(root) 

    root.mainloop() 

if __name__ == "__main__": 
    main() 
1

함수 ReadFile이 매개 변수를 받아 확인 :

def ReadFile(LayoutButton): 
    #Something Magical Happens 
    LayoutButton.config(state='active') 

LayoutButtonReadFile 전화 main 내부 함수를 정의합니다. 새로운 발생으로 ReadFile의 발생을 대체하십시오.

wrapper = lambda event=None: ReadFile(Layoutbutton). 

또는 클래스를 사용하여 프로그램을 구성 :

def main(): 
    #global Layoutbutton # No need to declare LayoutButton as global. 

    def wrapper(event=None):   # <------- 
     return ReadFile(Layoutbutton) # <------- 

    #setup root window yada yada yada 
    Layoutbutton=Button(root,text="Layout",command=wrapper,underline=0) # <-- 
    Layoutbutton.place(relx=.5,rely=.85,anchor=CENTER) 
    root.bind("l",DisplayLayout) 
    root.bind('L',DisplayLayout) 
    Layoutbutton.config(state='disabled') 

    BrowesButton=Button(root,text="File",command=wrapper,underline=0) # <-- 
    BrowesButton.place(relx=.75,rely=.85,anchor=CENTER) 
    root.bind("F", wrapper) # <------- 
    root.bind('f', wrapper) # <------- 

또는 대신 기능의 lambda를 사용할 수 있습니다.