2017-02-07 2 views
0

두 파이썬 클래스 사이에 전달하고자하는 데이터는 xy입니다. button을 클릭하면 command=lambda: controller.show_frame(PlotPage)을 실행하여 SelectPage (데이터 선택)에서 PlotPage (x 및 y를 표시)으로 전환합니다. 페이지 전환 전에 또는 button 람다 내에 xy을 저장하고 싶습니다. 데이터를 PlotPage으로 전달하는 가장 좋은 방법은 배열을 전역 변수로 저장하는 것입니까? 아니면이 배열을 버튼 람다 함수에 포함시키는 더 편리한 방법이 있습니까?파이썬 클래스 사이에 배열 전달하기

# possible global variables 
global x = [stuff x] 
global y = [stuff y]  

class SelectPage(tk.Frame): 
    def __init__(self,parent,controller): 
     button = tk.Button(self,text="Plot", 
      command=lambda: controller.show_frame(PlotPage), 
      [some_lambda_here]) # Possible lambda addition 

class PlotPage(tk.Frame): 
    def __init__(self,parent,controller): 
     [Tkinter plot intialization stuff] 
     plotData(x,y) # plotData creates the plot 

컨트롤러 클래스 :

class Project: 

def __init__(self, *args,**kwargs): 
    tk.Tk.__init__(self,*args,**kwargs) 
    container = tk.Frame(self) 

    container.pack(side="top",fill="both",expand=True) 

    container.grid_rowconfigure(0,weight=1) 
    container.grid_columnconfigure(0,weight=1) 

    self.frames = {} 

    for F in (SelectPage, PlotPage): 

     frame = F(container, self) 

     self.frames[F] = frame 

     frame.grid(row=0,column = 0, sticky = "nsew") 

    self.show_frame(StartPage) 

def show_frame(self, container): 

    frame = self.frames[container] 
    frame.tkraise() 
+0

컨트롤러의 클래스 란 무엇입니까? – daragua

+0

데이터를 포함하고'Frame' 객체에 의해 공유되는'Page' 객체를 갖는 것이 합리적이라고 생각합니다. –

+0

@daragua 컨트롤러 클래스를 보여주기 위해 코드가 업데이트되었습니다. –

답변

1

구성 요소 사이의 통신의 경우, 관찰자 ​​디자인 패턴과 MVC 아키텍처를 살펴 있어야합니다. 그런 다음이 선 (I 여기 Tk의 지침을 건너 뛰는거야)에 따라 프로그램을 구성 할 수 :

class Observable: 
    def __init__(self, signals): 
     # create signal map 
    def connect(self, signal, handler): 
     # append handler to the signal in the map 
    def emit(self, signal, *args, **kwargs): 
     # iterate over signal handlers for given signal 

class Model(Observable): 
    def __init__(self): 
     super().__init__("changed") 
     self.x = [] 
     self.y = [] 

    def set_x(self, x): 
     self.x = x 
     self.emit("changed") 

    def append_x(self, value): 
     self.x.append(value) 
     self.emit("changed") 

    # same for y 

class PlotView(SomeTKTClass): 
    def __init__(self, model): 
     self.model = model 
     model.connect("changed", lambda: self.plot(model.x, model.y)) 

    def plot(self, x, y): 
     #some tk rendering here 

# SelectPage and StartPage are defined somewhere. 

class MainController(SomeTkClass): 
    def __init__(self): 
     # ... 
     self.model = Model() 
     self.startPage = StartPage() # I suppose 
     self.plotView = PlotView(self.model) 
     self.selectPage = SelectPage() 
     self.frames = {} 

     for view in {self.startPage, self.plotView, self.selectPage}: 
      self.frames[view.__class__] = view 
      # ... 
     self.show_frame(StartPage) 

    def show_frame(self, container): 
     frame = self.frames[container] 
     # ... 

옵저버 패턴의 구현은 여러 가지 방법으로 수행 할 수 있습니다. 여기에 제안 된 것은 간단합니다. 이 대략적인 스케치를 개선 할 수있는 많은 방법이 있지만 관측 가능한 모델로 하여금 해당 데이터가 변경되었고 플롯에서 다시 그려 질 수 있음을 알리는 것이 관건입니다.

+0

Observer 패턴에 의견을 보내 주셔서 감사합니다! 이것과 [클래스에서 변수 데이터를 얻는 방법] (http://stackoverflow.com/questions/32212408/how-to-get-variable-data-from-a-class)과 함께이 문제를 해결할 수있었습니다. –

+1

도움이 되었기 때문에 기쁩니다. 옵서버 패턴의 구현에 관해서는, 만약 당신이 그것을 스스로한다면, 공통적 인 함정이있다 : 당신은 관찰자를 제거하지만 어떻게 든 그것은 여전히 ​​살아있다. Observable에 저장된 콜백에 대한 참조가 있기 때문에 유출되었습니다. 옵저버가 제거되면 콜백을 삭제하는 데주의를 기울여야합니다. – daragua

관련 문제