如何使“放置”布局管理器在此程序中工作?

时间:2019-02-10 17:48:15

标签: python tkinter

我一直在这里浏览页面切换示例:Switch between two frames in tkinter

我正在尝试使用“ place()”布局管理器对页面上的窗口小部件进行排序,但是每当我使用它时,它们根本就不会出现在页面上。对于要创建的程序,在打包和网格中使用它很重要,如何使它们工作?

例如,在下面的代码中,“欢迎”没有出现在“ StartTest”页面上。

import tkinter as tk
import random

title_font=("Microsoft Jhenghei UI Light", 35)

class MathsApp(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)
        self._frame = None
        self.switch_frame(StartTest)
        self.title("Maths Revision App")
        self.geometry("800x500")
        self.configure(bg="white")

    def switch_frame(self, frame_class):
        """Destroys current frame and replaces it with a new one."""
        new_frame = frame_class(self)
        if self._frame is not None:
            self._frame.destroy()
        self._frame = new_frame
        self._frame.pack()

class StartTest(tk.Frame):
    def __init__(self, master):
        tk.Frame.__init__(self, master)
        #welcome label
        tk.Label(self, text="Welcome!", font=title_font, bg="white", fg="#004d99").place(x=30, y=20)
        tk.Button(self, text="Open page one",
              command=lambda: master.switch_frame(PageOne)).pack()
        tk.Button(self, text="Open page two",
              command=lambda: master.switch_frame(PageTwo)).pack()

class PageOne(tk.Frame):
    def __init__(self, master):
        tk.Frame.__init__(self, master)
        tk.Label(self, text="This is page one").pack(side="top", fill="x", pady=10)
        tk.Button(self, text="Return to start page",
              command=lambda: master.switch_frame(StartTest)).pack()

class PageTwo(tk.Frame):
    def __init__(self, master):
        tk.Frame.__init__(self, master)
        tk.Label(self, text="This is page two").pack(side="top", fill="x", pady=10)
        tk.Button(self, text="Return to start page",
              command=lambda: master.switch_frame(StartTest)).pack()

if __name__ == "__main__":
    app = MathsApp()
    app.mainloop()

我尝试删除页面上的其他按钮,但“欢迎”标签仍然没有显示。

1 个答案:

答案 0 :(得分:0)

您使用place是问题的根源,但真正的问题是您做出的三种选择的组合:

  1. 您正在pack中的按钮上使用StartTest,而不是标签上的
  2. StartTest添加到根窗口时,并不是在告诉它填充窗口,
  3. 在创建按钮之前,先创建“欢迎”标签,使其出现在按钮后面。

最终结果是StartTest刚好足以容纳按钮,并且按钮位于标签的顶部。标签在那里,但是由于您做出了所有其他选择,因此很难看到它。

这可以通过将欢迎标签移动到按钮顶部来说明。更改您的__init__,使其最后创建标签:

class StartTest(tk.Frame):
    def __init__(self, master):
        tk.Frame.__init__(self, master, background="bisque")
        tk.Button(self, text="Open page one",
              command=lambda: master.switch_frame(PageOne)).pack()
        tk.Button(self, text="Open page two",
              command=lambda: master.switch_frame(PageTwo)).pack()
        tk.Label(self, text="Welcome!, blah blah blah blah", font=title_font, bg="white", fg="#004d99").place(x=30, y=20)

这是您的窗口的外观(我将窗口大小减小到300x200以保持图像较小):

enter image description here

问题的下一部分是框架没有填满窗口。通过为您的StartTest提供独特的颜色以使其突出即可轻松说明。

__init__函数更改为像这样开始(请注意在第三行中使用“红色”颜色):

class StartTest(tk.Frame):
    def __init__(self, master):
        tk.Frame.__init__(self, master, background="red")
        ...

运行它时,请注意屏幕上的任何地方都没有红色。这暗示我们看不到框架。在这种情况下,这是因为它已经缩小以适合按钮,而其他选项导致按钮完全填充了背景(即:没有填充将允许背景显示出来)。

要解决此问题,您需要更改在pack内部调用show_frame的方式。您需要确保框架完全填满窗口。为此,可以将pack命令更改为如下形式:

self._frame.pack(fill="both", expand=True)

所有这些更改一起显示在窗口中,如下所示:

enter image description here

如您所见,内部框架现在充满了窗口,并且整个标签可见。我怀疑它是否在您期望的位置,但是至少现在您可以看到它了,并希望更好地了解为什么以前看不到它。