Python 3.x 如何在tkinter中切换帧

Python 3.x 如何在tkinter中切换帧,python-3.x,tkinter,Python 3.x,Tkinter,目前正在抵制将我的笔记本电脑扔出窗外并在此时用球棒砸碎它的诱惑 目前,我正在尝试创建一个简单的GUI,它曾经是一个基于文本的RPG游戏。但是尝试使用GUI让我想死 我只想有一个可伸缩的方式来交换游戏中的帧。目前存在主菜单和正在工作的角色创建屏幕,因为我甚至无法让它正常工作 我已经尝试了在这个网站和discord服务器上可以找到的大多数东西,我似乎每次都会遇到新的错误 我只是想知道如何在这两者之间交换,因为尝试任何我能在网上找到的东西只会产生更多的错误。 因为这是一款游戏,所以会有更多的屏幕,所以

目前正在抵制将我的笔记本电脑扔出窗外并在此时用球棒砸碎它的诱惑

目前,我正在尝试创建一个简单的GUI,它曾经是一个基于文本的RPG游戏。但是尝试使用GUI让我想死

我只想有一个可伸缩的方式来交换游戏中的帧。目前存在主菜单和正在工作的角色创建屏幕,因为我甚至无法让它正常工作

我已经尝试了在这个网站和discord服务器上可以找到的大多数东西,我似乎每次都会遇到新的错误

我只是想知道如何在这两者之间交换,因为尝试任何我能在网上找到的东西只会产生更多的错误。 因为这是一款游戏,所以会有更多的屏幕,所以一个可扩展的解决方案将是完美的,谢谢

import tkinter
from tkinter import *
from tkinter import ttk
from PIL import ImageTk, Image

root = Tk()
content = ttk.Frame(root)
root.geometry("600x600")

class CharacterCreate(tkinter.Frame):
    def __init__(self, parent):
        tkinter.Frame.__init__(self)
        self.parent = parent

        backgroundchar = ImageTk.PhotoImage(Image.open("plont2.png"))
        backgroundlabelchar = tkinter.Label(content, image = backgroundchar)
        backgroundlabelchar.image = backgroundchar
        backgroundlabelchar.grid(row=1,column=1)

        Charname = tkinter.Label(content, text = "Enter your character name here:").grid(row=0)

        e1 = tkinter.Entry(content)
        e1.grid(row=0, column=1)
        e1.lift()

        CharBtn1 = Button(content, text="Return to main menu", width = 15, height = 1)
        CharBtn1.grid(row=2, column=2)
        CharBtn1.lift()

class MainMenu(tkinter.Frame):
    def __init__(self, parent):
        tkinter.Frame.__init__(self)
        self.parent = parent

        background = ImageTk.PhotoImage(Image.open("bred.png"))

        content.grid(column=1, row=1)

        Btn1 = Button(content, text="Play", width=5, height=1, command = CharacterCreate.lift(1))
        Btn2 = Button(content, text="Quit", width=5, height=1, command = root.quit)

        backgroundlabel = tkinter.Label(content, image=background)
        backgroundlabel.image = background

        backgroundlabel.grid(row=1, column=1)

        Btn1.grid(row=1, column=1, padx=(50), pady=(50))
        Btn1.columnconfigure(1, weight=1)
        Btn1.rowconfigure(1, weight=1)
        Btn1.lift()

        Btn2.grid(row=1, column=2, padx=(50), pady=(50))
        Btn2.columnconfigure(2, weight=1)
        Btn2.rowconfigure(1, weight=1)
        Btn2.lift()

MainMenu(1)

root.mainloop()

您有五个主要问题:

您正在立即调用函数command=CharacterCreate.lift1,而不是在单击按钮时调用command=CharacterCreate.lift, 您正在向lift传递一个无效参数-您正在传递1,但lift的参数必须是另一个小部件, 您正在类上调用lift,而不是类的实例。 您从未创建CharacterCreate的实例 您的类继承自框架,但您从不将这些类用作框架——它们都将其小部件直接放置在容器中 在页面之间切换通常涉及两种技术之一:在启动时创建所有帧,然后将活动帧提升到其他帧之上,或者销毁当前帧并重新创建活动帧。你似乎在尝试做后者,所以这个答案将告诉你如何做

由于修复您的程序将需要许多更改,因此我将向您展示一个模板,您可以使用它重新开始

让我们从导入开始,然后是页面的定义。为了保持示例简短,每个类都有一个标签,以便您能够区分它们注意:将tkinter作为tk导入只是为了使代码更易于阅读和键入:

import tkinter as tk

class CharacterCreate(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)

        label = tk.Label(self, text="I am CharacterCreate")
        label.pack(padx=20, pady=20)

class MainMenu(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)

        label = tk.Label(self, text="I am MainMenu")
        label.pack(padx=20, pady=20)
您的原始代码创建了一个容器,因此我们接下来将这样做。我们还需要创建根窗口:

root = tk.Tk()

container = tk.Frame(root)
container.pack(fill="both", expand=True)
现在我们需要为每个页面创建一个实例,将容器作为父级。根据经验,创建小部件的代码应该是在小部件上调用pack、place或grid的代码,所以我们也必须这样做。我们需要确保网格配置为将所有权重赋予第0行第0列

main = MainMenu(container)
cc = CharacterCreate(container)

main.grid(row=0, column=0, sticky="nsew")
cc.grid(row=0, column=0, sticky="nsew")

container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
我们需要一种方法使一个班级高于另一个班级。这最好由函数来处理。为了使代码更容易理解,我们将把页面保存在字典中,以便按名称引用它们。此名称将是函数的参数

pages = {"cc": cc, "main": main}
def switch(name):
    page = pages[name]
    page.lift()
最后,我们需要从顶部的主菜单开始,我们需要启动事件循环:

switch('main')
root.mainloop()
这样,您就有了一个运行并显示主菜单的程序。为了完成该示例,让我们向菜单添加一个按钮以切换到创建页面,并在创建页面中创建一个按钮以切换回菜单

首先,在主菜单的uuu init_uuuu中,在创建标签的代码之后添加以下内容。请注意,因为我们需要将参数传递给switch,所以我们使用lambda:

接下来,在CharacterCreate的u_init__;中,在创建标签的代码之后添加以下内容:

button = tk.Button(self, text="Go to main menu", command=lambda: switch('main'))
button.pack()

这样,您就拥有了创建任意多个页面的基本结构,并且可以轻松地按名称切换到这些页面。

如果不需要图像来重现问题,我建议您出于本问题的目的从代码中删除它们。
button = tk.Button(self, text="Go to main menu", command=lambda: switch('main'))
button.pack()