如何在Tkinter中切换帧

时间:2019-07-22 16:59:56

标签: python-3.x tkinter

目前正在抵制将笔记本电脑丢出窗户并用蝙蝠砸碎笔记本的诱惑。

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

我只想有一种可缩放的方式来在游戏中的帧之间交换。 (当前存在主菜单和“正在进行中的角色创建”屏幕,因为我什至无法设法使它正常工作。)

我已经尝试了大多数可以在本网站和不和谐的服务器上找到的东西,而且每次似乎都得到一个新的错误。

我只是想知道如何在这些之间进行交换,因为尝试任何我可以在网上找到的东西都会造成更多错误。 由于这是一款游戏,因此还会有更多的“屏幕”出现,因此可扩展的解决方案将是完美的感谢。

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()

1 个答案:

答案 0 :(得分:0)

您有五个主要问题:

  • 您正在立即(command=CharacterCreate.lift(1))而不是在单击按钮(command=CharacterCreate.lift)时调用函数,
  • 您要传递一个无效的参数来提升-您正在传递1,但是lift的参数必须是另一个小部件,
  • 您是在类而不是类的实例上调用lift
  • 您永远不会创建CharacterCreate的实例
  • 您的类继承自Frame,但您永远不要将这些类用作框架-它们各自将其小部件直接放置在container

在页面之间切换通常涉及以下两种技术之一:在启动时创建所有框架,然后将活动框架提升到其他框架之上,或者破坏当前框架并重新创建活动框架。您似乎正在尝试执行后者,因此此答案将向您展示如何做到这一点。

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

让我们从导入开始,然后是页面的定义。为了使示例简短,每个类将有一个标签,以便您可以区分它们(注意:“以tk的方式导入tkinter只是为了使代码易于阅读和键入而已”):

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)

现在,我们需要为每个页面创建一个实例,为它们提供容器作为父页面。根据经验,创建窗口小部件的代码应该是在窗口小部件上调用packplacegrid的代码,因此我们也必须这样做。我们需要确保将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()

这样,您就可以运行一个程序并显示主菜单。最后,让我们在菜单中添加一个按钮以切换到创建页面,然后在创建页面中创建一个按钮以切换回到菜单。

首先,在__init__的{​​{1}}内,在创建标签的代码后添加以下内容。注意,因为我们需要将参数传递给MainMenu,所以我们使用switch

lambda

然后,在button = tk.Button(self, text="Go to creater", command=lambda: switch('cc')) button.pack() 的{​​{1}}内,在创建标签的代码之后添加以下内容:

__init__

有了它,您现在已经具有创建所需页面的基本结构,并可以按名称轻松切换到它们。