2017-02-07 73 views
0

2つのPythonクラスの間で渡したいデータをxyの配列にします。 buttonをクリックするとcommand=lambda: controller.show_frame(PlotPage)を実行してSelectPage(データを選択)からPlotPage(xとyをプロット)に切り替わります。ページスイッチの前、またはbuttonラムダ内には、xyが保存されています。グローバル変数として配列を保存して、データをPlotPageに渡す最善の方法か、これらの配列をボタンのラムダ関数に含める方が便利ですか?Pythonクラス間で配列を渡す

# 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アーキテクチャを見ている必要があります。その後、(私はここ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] 
     # ... 

Observerパターンの実装は、多くの方法で行うことができます。ここに示唆されているのは単純です。この大まかなスケッチを改善する方法はたくさんありますが、観察可能なモデルにデータが変更され、プロット内に再描画できることをビューに通知させることです。

+0

Observerパターンの入力に感謝します!これと[クラスからの可変データの入手方法](http://stackoverflow.com/questions/32212408/how-to-get-variable-data-from-a-class)と一緒に問題を解決することができました –

+1

私はそれが助けてうれしいです。 Observerパターンの実装に関して、あなたがそれを自分自身で行うと、共通の落とし穴があります:あなたはオブザーバーを削除しますが、何とかそれはまだ生きています。 Observableに格納されているコールバックには参照が保持されているため、リークしています。オブザーバーが取り除かれたら、オブザーバーがインストールしたコールバックを削除するように注意することが重要です。 – daragua

関連する問題