2017-09-11 10 views
1

Brian이 "tkinter에서 두 프레임 전환"에 대한 MVC model을 따릅니다. 그는 서로의 위에 프레임을 겹쳐 쌓습니다. (모두 처음부터 만들어졌습니다) 우리는 의지대로 프레임을 보여줍니다.MVC 모델. 프레임 간 전환, 새 프레임 추가

프로그램을 실행하기 시작한 후에 다른 프레임을 추가 할 수 있습니까? 아니면 처음에 만들어진 것보다 프레임을 볼 수 있습니까? (주어진 답변 덕분에 나는 그것을하는 방법을 생각할 수있었습니다)

그러나 100 % 독립 적이기 때문에 페이지 2에는 여전히 문제가 있습니다. 프레임을 호출 할 때마다 스트레치에서 시작하지 않습니다.

다음은 코드를 수정 한 내용입니다.

import tkinter as tk    # python 3 
from tkinter import font as tkfont # python 3 
#import Tkinter as tk  # python 2 
#import tkFont as tkfont # python 2 

class SampleApp(tk.Tk): 

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

     self.title_font = tkfont.Font(family='Helvetica', size=18, weight="bold", slant="italic") 

     # the container is where we'll stack a bunch of frames 
     # on top of each other, then the one we want visible 
     # will be raised above the others 
     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 (StartPage, PageOne): 
      page_name = F.__name__ 
      frame = F(parent=container, controller=self) 
      self.frames[page_name] = frame 

      # put all of the pages in the same location; 
      # the one on the top of the stacking order 
      # will be the one that is visible. 
      frame.grid(row=0, column=0, sticky="nsew") 

     self.show_frame("StartPage") 

    def show_frame(self, page_name): 
     '''Show a frame for the given page name''' 
     frame = self.frames[page_name] 
     frame.tkraise() 

    def add_PageTwo (self): 

     self.title_font = tkfont.Font(family='Helvetica', size=18, weight="bold", slant="italic") 

     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["PageTwo"] = PageTwo(parent=container, controller=self) 
     self.frames["PageTwo"].grid(row=0, column=0, sticky="nsew")   

     self.show_frame("PageTwo") 


class StartPage(tk.Frame): 

    def __init__(self, parent, controller): 
     tk.Frame.__init__(self, parent) 
     self.controller = controller 
     label = tk.Label(self, text="This is the start page", font=controller.title_font) 
     label.pack(side="top", fill="x", pady=10) 

     button2 = tk.Button(self, text="Go to Page One", 
         command=lambda: controller.show_frame("PageOne")) 
     button2.pack() 

class PageOne(tk.Frame): 

    def __init__(self, parent, controller): 
     tk.Frame.__init__(self, parent) 
     self.controller = controller 
     label = tk.Label(self, text="This is page 1", font=controller.title_font) 
     label.pack(side="top", fill="x", pady=10) 
     button1 = tk.Button(self, text="Go to the page 2", 
          command=lambda: controller.add_PageTwo()) 
     button1.pack() 
     button2 = tk.Button(self, text="Go to the start page", 
          command=lambda: controller.show_frame("StartPage")) 
     button2.pack()   

class PageTwo(tk.Frame): 

    def __init__(self, parent, controller): 
     tk.Frame.__init__(self, parent) 
     self.controller = controller 
     label = tk.Label(self, text="This is page 2. GREAT", font=controller.title_font) 
     label.pack(side="top", fill="x", pady=10) 
     button = tk.Button(self, text="Go to the start page", 
          command=lambda: controller.show_frame("StartPage")) 
     button.pack() 


if __name__ == "__main__": 
    app = SampleApp() 
    app.mainloop() 
+0

새 프레임을 만드는 데 문제가 없습니다. 다른 프레임이 클래스 속성이거나 목록 또는 dict 같은 속성 인 경우이 새 프레임을 기존 프레임에 추가 할 수 있습니다. –

+0

@SierraMountainTech 감사합니다. 내 대답에서 볼 수 있듯이 (거의) 그 문제를 해결했습니다. – ogeretal

답변

1

오류는 PageNew 클래스 정의에 놓여 : 당신은 아마 당신의 __init__ 방법의 매개 변수로 전달하는 의미있는 동안, 괄호 안의

class PageNew(tk.Frame, parent, controller): 
    ... 

이름은 PageNew이 상속있는 클래스이다 .

스크립트의이 시점에서 parentparent이라는 모듈 수준 변수를 나타냅니다. 그러나 그러한 변수는 존재하지 않으므로 NameError이됩니다.

이것을 제거하고 tk.Frame 만 유지해야합니다.

class PageNew(tk.Frame): 
    ... 

귀하의 질문에 그렇습니다. 예, 런타임에 프레임을 생성 한 다음 보여줄 수 있습니다. 초기화 할 때 모두 생성 할 필요는 없습니다.

+0

답변 해 주셔서 감사합니다. 나는 그것을 사용하고 질문에 나의 새로운 해결책을 게시한다. 거의 다 왔어 ... – ogeretal