简体   繁体   English

如何使tkinter程序转到前一帧?

[英]How can I make a tkinter program go to a previous frame?

I'm building a small program where different parts of the code will call on one object different times. 我正在构建一个小程序,其中代码的不同部分将在不同时间调用一个对象。 I'd like to try and make it call the previous frame back instead of duplicating the actual code multiple times. 我想尝试使其返回上一帧,而不是多次重复实际代码。 Here is part of my code if you need an example: 如果您需要一个示例,这是我的代码的一部分:

    #Console Menu
    class consoleMenu(tk.Frame):

        #Initialize
        def __init__(self, parent, controller):
            tk.Frame.__init__(self, parent)

            #Setups
            consoleGuideLabel = ttk.Label(self, text = "Console Guide", font = LARGE_FONT)

            consoleItemInfoButton = ttk.Button(self, text = "Console Item Info", command = lambda: controller.show_frame(consoleItemInfo))
            consoleVersionButton = ttk.Button(self, text = "Console Version History", command = lambda: popupmsg ("Not supported just yet!"))
            consoleMainMenuButton = ttk.Button(self, text = "Main Menu", command = lambda: controller.show_frame(StartPage))

            #Placement
            consoleGuideLabel.pack(pady = 10, padx = 10)

            consoleItemInfoButton.pack()
            consoleVersionButton.pack()
            consoleMainMenuButton.pack()

Now this is the part that gets called on multiple times by different frames. 现在,这是被不同框架多次调用的部分。

    #Air - MCPE, PC, Xbox
    class mc_air(tk.Frame):

        #Initialize
        def __init__(self, parent, controller):
            tk.Frame.__init__(self, parent)

            #Item Info
            text_file = open("minecraft_air.txt", "r")
            file = text_file.read()
            text_file.close()

            #Setups
            airLabel = ttk.Label(self, text = "Minecraft - Air - 1", font = LARGE_FONT)
            airInfo = ttk.Label(self, text = file, font = NORMAL_FONT)
            exitButton = ttk.Button(self, text = "Return to Menu", command = lambda: controller.show_frame(StartPage))

            #Placement
            airLabel.pack(pady = 10, padx = 10)
            airInfo.pack()
            exitButton.pack()

Where it says: 它说:

exitButton = ttk.Button(self, text = "Return to Menu", command = lambda:      controller.show_frame(StartPage))

I'd like to be able to replace StartPage with a command to go to the previous window. 我希望能够使用命令替换StartPage转到上一个窗口。

Here is one possible implementation, based on my implementation of frame switching here : 这是一个可能的实现,基于我这里的帧切换实现:

import Tkinter as tk

class BaseFrame(tk.Frame):
    """An abstract base class for the frames that sit inside PythonGUI.

    Args:
      master (tk.Frame): The parent widget.
      controller (PythonGUI): The controlling Tk object.

    Attributes:
      controller (PythonGUI): The controlling Tk object.

    """

    def __init__(self, master, controller):
        tk.Frame.__init__(self, master)
        self.controller = controller
        self.grid()
        self.create_widgets()

    def create_widgets(self):
        """Create the widgets for the frame."""
        raise NotImplementedError

    def goto_three(self):
        self.controller.frames[FrameThree].return_to(self.__class__)
        self.controller.show_frame(FrameThree)


class FrameOne(BaseFrame):
    """First page."""

    def create_widgets(self):
        """Create the base widgets for the frame."""
        self.button_two = tk.Button(self,
                                    anchor=tk.W,
                                    command=lambda: self.controller.show_frame(FrameTwo),
                                    padx=5,
                                    pady=5,
                                    text="Two")
        self.button_two.grid(padx=5, pady=5, sticky=tk.W+tk.E)
        self.button_three = tk.Button(self,
                                      anchor=tk.W,
                                      command=self.goto_three,
                                      padx=5,
                                      pady=5,
                                      text="Three")
        self.button_three.grid(padx=5, pady=5, sticky=tk.W+tk.E)


class FrameTwo(BaseFrame):
    """Second page."""

    def create_widgets(self):
        """Create the base widgets for the frame."""
        self.button_one = tk.Button(self,
                                    anchor=tk.W,
                                    command=lambda: self.controller.show_frame(FrameOne),
                                    padx=5,
                                    pady=5,
                                    text="One")
        self.button_one.grid(padx=5, pady=5, sticky=tk.W+tk.E)
        self.button_three = tk.Button(self,
                                      anchor=tk.W,
                                      command=self.goto_three,
                                      padx=5,
                                      pady=5,
                                      text="Three")
        self.button_three.grid(padx=5, pady=5, sticky=tk.W+tk.E)


class FrameThree(BaseFrame):
    """Third page."""

    def create_widgets(self):
        """Create the base widgets for the frame."""
        self.button_two = tk.Button(self,
                                    anchor=tk.W,
                                    command=lambda: self.controller.show_frame(FrameTwo),
                                    padx=5,
                                    pady=5,
                                    text="Two")
        self.button_two.grid(padx=5, pady=5, sticky=tk.W+tk.E)
        self.button_one = tk.Button(self,
                                    anchor=tk.W,
                                    command=lambda: self.controller.show_frame(FrameOne),
                                    padx=5,
                                    pady=5,
                                    text="One")
        self.button_one.grid(padx=5, pady=5, sticky=tk.W+tk.E)
        self.button_back = tk.Button(self,
                                     anchor=tk.W,
                                     padx=5,
                                     pady=5,
                                     text="Back")
        self.button_back.grid(padx=5, pady=5, sticky=tk.W+tk.E)

    def return_to(self, frame):
        self.button_back.config(command=lambda: self.controller.show_frame(frame))


class PythonGUI(tk.Tk):
    """The main window of the GUI.

    Attributes:
      container (tk.Frame): The frame container for the sub-frames.
      frames (dict of tk.Frame): The available sub-frames.

    """

    def __init__(self):
        tk.Tk.__init__(self)
        self.title("Python GUI")
        self.create_widgets()
        self.resizable(0, 0)

    def create_widgets(self):
        """Create the widgets for the frame."""             
        #   Frame Container
        self.container = tk.Frame(self)
        self.container.grid(row=0, column=0, sticky=tk.W+tk.E)

        #   Frames
        self.frames = {}
        for f in (FrameOne, FrameTwo, FrameThree): # defined subclasses of BaseFrame
            frame = f(self.container, self)
            frame.grid(row=2, column=2, sticky=tk.NW+tk.SE)
            self.frames[f] = frame
        self.show_frame(FrameOne)

    def show_frame(self, cls):
        """Show the specified frame.

        Args:
          cls (tk.Frame): The class of the frame to show. 

        """
        self.frames[cls].tkraise()

if __name__ == "__main__":
    app = PythonGUI()
    app.mainloop()
    exit()

It's a bit hacky as it stands, but basically the idea is that goto_three calls the FrameThree instance's return_to , which alters the command on its button_back to return to whichever frame it was called from. 就目前情况而言,这有点goto_three ,但是基本上的想法是goto_three调用FrameThree实例的return_to ,这会改变其button_back上的command以返回到从其button_back任何帧。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM