当前位置: 首页 > 面试题库 >

Python-在tkinter的两个帧之间切换

牟华翰
2023-03-14
问题内容

正如教程向我展示的那样,我已经在最初的几个脚本上构建了一个不错的GUI,但是没有一个脚本解决更复杂的程序的问题。

如果在打开屏幕上有带有“开始菜单”的内容,并且在用户选择后移动到程序的其他部分并适当地重画屏幕,那么执行此操作的优雅方法是什么?

是否只是.destroy()一个“开始菜单”框架,然后创建一个新的窗口小部件,并填充另一部分的小部件?并在他们按下“后退”按钮时逆转此过程?


问题答案:

一种方法是将框架堆叠在一起,然后可以按照堆叠顺序将一个框架升高到另一个框架之上。最上面的一个将是可见的。如果所有框架的尺寸都相同,则效果最好,但是只需一点点工作,即可使其适用于任何尺寸的框架。

注意:为了使此功能起作用,页面的所有小部件都必须具有该页面(即:)self或后代作为父项(或母版,取决于你喜欢的术语)。

这是一个人为的例子,向你展示一般概念:

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, PageTwo):
            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()


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)

        button1 = tk.Button(self, text="Go to Page One",
                            command=lambda: controller.show_frame("PageOne"))
        button2 = tk.Button(self, text="Go to Page Two",
                            command=lambda: controller.show_frame("PageTwo"))
        button1.pack()
        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)
        button = tk.Button(self, text="Go to the start page",
                           command=lambda: controller.show_frame("StartPage"))
        button.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", 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()

如果在类中发现创建实例的概念令人困惑,或者在构造过程中不同的页面需要不同的参数,则可以分别显式调用每个类。该循环主要用于说明每个类都相同的观点。

例如,要单独创建类,可以删除循环(for F in (StartPage, ...)使用以下命令:

self.frames["StartPage"] = StartPage(parent=container, controller=self)
self.frames["PageOne"] = PageOne(parent=container, controller=self)
self.frames["PageTwo"] = PageTwo(parent=container, controller=self)

self.frames["StartPage"].grid(row=0, column=0, sticky="nsew")
self.frames["PageOne"].grid(row=0, column=0, sticky="nsew")
self.frames["PageTwo"].grid(row=0, column=0, sticky="nsew")


 类似资料:
  • 问题内容: 我想在Python中的两个值之间切换,即0到1之间。 例如,当我第一次运行一个函数时,它产生数字0。下一次,它产生1。第三次它返回零,依此类推。 抱歉,如果这样做没有道理,但是有人知道这样做的方法吗? 问题答案: 用途: 请注意,如果您需要比更为复杂的周期,那么此解决方案将比此处发布的其他解决方案更具吸引力。

  • 假设你有两个活动-A和B,你从A开始B。在B中,你有一个任务。如果任务完成,您希望返回到按下when back键,如果没有,您希望取消整个应用程序。但在解除后,你可以从最近的应用程序菜单中恢复B。如果在那之后你需要同样的后退键的行为。 因此,我想放弃一个活动或整个应用程序(但简历的可能性)。有什么办法可以做到这一点吗?

  • 我是JavaFX的新手,我需要在两个没有菜单栏的锚窗格之间切换,但锚窗格本身中有注册按钮,它应该切换到注册表单表单登录表单我正在使用Scene Builder生成.fxml文件, 我的问题是如何以一种简单的方式做到这一点?loginform与注册按钮 ERRRO是 null main.java controller.java 我的问题是如何在main.java中加载register form,在单

  • 我有两个数据帧df1和df2,其中df2是df1的子集。我如何获得一个新的数据帧(df3),它是两个数据帧之间的差值? 换句话说,一个数据帧,它包含了df1中所有的行/列,而不是DF2中的行/列?

  • 问题内容: 我正在寻找一种方法,当单击某些内容时,可以运行两个单独的操作/函数/“代码块”,然后在再次单击同一内容时,运行一个完全不同的块。我把这个放在一起。我想知道是否有更有效/更优雅的方法。我知道jQuery.toggle(),但是有点烂。 问题答案: jQuery有两个称为的方法。在另一个 [文件] 不正是你想要的click事件。 注意: 似乎至少从 jQuery 1.7开始 ,此版本已 弃

  • 我试图修改数据帧以仅包含列中的值介于99和101之间的行,并尝试使用下面的代码执行此操作。 然而,我得到了错误 ValueError:序列的真值不明确。使用a.empty、a.bool()、a.item()、a.any()或a.all() 我想知道是否有一种不用循环就能做到这一点的方法。