2017-09-11 5 views
1

Ich folge dem MVC model, den Brian auf der Antwort auf "Wechseln zwischen zwei Frames in tkinter" gemacht hat. Er stapelt die Rahmen aufeinander (alle sind gleich am Anfang) und dann zeigen wir sie einfach nach unserem Willen.MVC tkinter Modell. Wechsle zwischen Frames, füge neue hinzu

Ist es möglich, einen anderen Frame hinzuzufügen, nachdem das Programm gestartet wurde oder nur mit diesem Modell können Sie die Frames anzeigen, als am Anfang gemacht wurden? (Dank der gegebenen Antworten konnte ich herausfinden, wie es geht)

Aber es gibt immer noch ein Problem mit Seite zwei, da es nicht 100% unabhängig ist. Jedes Mal, wenn es den Frame aufruft, beginnt es nicht von strach.

Die folgenden Änderungen wurden am Code vorgenommen.

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

Es ist kein Problem, neue Frames zu machen. Wenn die anderen Frames entweder ein Klassenattribut sind oder sich in einer Liste oder einem Dict befinden, das ein Attribut ist, können Sie diesen neuen Frame zu einem bestehenden Frame hinzufügen. –

+0

@SierraMountainTech Vielen Dank. Ich habe (fast) dieses Problem gelöst, wie Sie in meiner Antwort sehen können. – ogeretal

Antwort

1

Der Fehler liegt bei der PageNew Klassendefinition:

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

Die Namen in Klammern sind die Klassen, von denen PageNew erben, während Sie sie vielleicht als Parameter Ihrer __init__ Methode gemeint passieren .

An dieser Stelle des Skripts würde sich parent auf eine Modulebenevariable mit dem Namen parent beziehen. Eine solche Variable existiert jedoch nicht, woraus sich ein NameError ergibt.

Sie müssen diese entfernen und nur tk.Frame behalten.

Wie für Ihre Frage, ja, ist es möglich, Frames zur Laufzeit zu erstellen, und dann zeigen sie. Sie müssen nicht alle bei der Initialisierung erstellt werden.

+0

Danke für Ihre Antwort. Ich habe es benutzt und poste meine neue Lösung in der Frage. Fast dort ... – ogeretal

Verwandte Themen