Tkinter! Understanding how to switch frames

后端 未结 1 1259
我寻月下人不归
我寻月下人不归 2020-12-03 08:53

Im trying to teach my self how to use tkinter and I found a useful code through youtube that I don\'t really fully understand. Would appreciate it if some could help me unde

相关标签:
1条回答
  • 2020-12-03 09:31
    import tkinter as tk  # why not from tkinter import? **
    

    Why not from tkinter import *? Because that is the wrong way to do it. Global imports are bad. Tkinter tutorials tend to do it the wrong way for some reason that I don't understand.

    The reason for the as tk part is so that you can do tk.Frame rather than Tkinter.Frame, making the code a little easier to type and a little easier to read. It's completely optional.


    class SampleApp(tk.Tk): 
    

    tk is the name of the tkinter module that was imported. Tk is the name of a class in that module that represents the root window. Every tkinter application must have a single root window. By placing it inside of SampleApp, this creates a subclass of this widget -- a copy that has additional features.

    It's not necessary to inherit from tk.Tk. You can inherit from tk.Frame, any other tkinter widget, or even object. It's a personal preference. The choice makes some things easier, some things harder.


    container = tk.Frame(self)
    

    The above creates an instance of a Frame widget, which will be used as a container for other "pages". These "pages" will all be stacked on top of each other in this container.


    frame = F(container, self)
    

    F is the loop variable. The loop is iterating over a list of classes, so each time through the loop F will be representing a class. F(...) creates an instance of the class. These classes (StartPage, PageOne, PageTwo) all require two parameters: a widget that will be the parent of this class, and an object that will server as a controller (a term borrowed from the UI patter model/view/controller).

    The line of code creates an instance of the class (which itself is a subclass of a Frame widget), and temporarily assigns the frame to the local variable frame.

    By passing self as the second ("controller") parameter, these new class instances will be able to call methods in the SampleApp class object.

    This saves a reference to the just-created frame in a dictionary. The key to the dictionary is the page name (or more accurately, the name of the class).

    This is how the show_frame method can determine the actual page widget just from the name of the class.

    Creating the frames in a loop is functionally equivalent to the following:

    f1 = StartPage(container, self)
    f2 = PageOne(container, self)
    f3 = PageTwo(container, self)
    
    f1.grid(row=0, column=0, sticky="nsew")
    f2.grid(row=0, column=0, sticky="nsew")
    f3.grid(row=0, column=0, sticky="nsew")
    
    self.frames = {"StartPage": f1, "PageOne": f2, "PageTwo": f3}
    

    frame.tkraise() 
    

    In nearly all GUI toolkits -- tkinter included -- there is the notion of a "stacking order": the order in which things are stacked. Some toolkits might call this the z-order. If two or more widgets are stacked on top of each other (which this code does by putting all pages in the same row and column), the widget that is on the top of the stack is the widget that will typically be visible.

    tkraise is a method of a Frame object that will raise the frame to the top of the stacking order. In this line of code, frame refers to one particular instance of one of the pages.


    tk.Frame.__init__(self, parent)
    

    Because each page is a subclass of a tk.Frame class, this calls the constructor of the parent class. This is necessary to initialize all of the internal structures that make up the actual frame widget. Although a Frame can take many options, this code chooses to send in only one -- a reference to another widget which is to act as the parent of this new widget.


    self.controller = controller
    

    The above code is simply "remembering" the value of the controller variable which was passed in. In this case, the controller is the application. By saving it off, this class can call methods on the SampleApp object.


    Note: the code in the question came from a tutorial that copied code from this answer: https://stackoverflow.com/a/7557028/7432. I am the author of that original code, but not the author of the tutorial. In that original answer are links to other questions related to this code.

    0 讨论(0)
提交回复
热议问题