【问题标题】:Cannot create frame in Toplevel window无法在顶层窗口中创建框架
【发布时间】:2018-12-04 13:25:14
【问题描述】:

我有 1 个根窗口和一个顶层窗口,我想把东西放在顶层窗口的框架中。但是,框架(而不是其中的标签)出现在根窗口中。

窗口的屏幕截图。

from tkinter import *

root = Tk()

Label(root, text="label1").pack()

newWindow = Toplevel(root)

Label(newWindow, text="label2").pack()
frame2 = Frame(newWindow).pack()
Label(frame2, text="framelabel2").pack()

root.mainloop()

【问题讨论】:

  • 您没有顶级窗口。您已经定义了两次tk() 并应用了一个主循环顶部root
  • @Mike-SMT 哎呀,不小心粘贴了我的旧代码,我刚刚更新了它。
  • 你想做什么?您需要在同一个窗口中使用两个标签吗?或者您是否需要在不同的窗口中使用每个标签?如果您使用网格选项而不是打包来定位框架,这可能会很有用。
  • @ParvBanks 这个问题很简单,就是在容器frame2 的新行上应用几何管理。
  • 检查我的答案,我使用网格来对齐标签。

标签: python python-3.x tkinter frame toplevel


【解决方案1】:

您需要像这样将frame2 打包在新的一行中:

from tkinter import *

root = Tk()

Label(root, text="label1").pack()

newWindow = Toplevel(root)

Label(newWindow, text="label2").pack()
frame2 = Frame(newWindow)
frame2.pack() # pack frame2 on new line here.
Label(frame2, text="framelabel2").pack()

root.mainloop()

framelabel2 标签放置在根窗口上的原因是 frame2 == 到 None,因为 pack() 返回 None。因为您尝试将小部件打包到 None tkinter 会将该小部件默认为根窗口,以尝试将该小部件放置在某处。

简单的解决方法是确保在定义框架或任何容器时始终在新行上使用pack()grid()place()

【讨论】:

  • 或者真的只是不要将.pack().grid().place() 分配给任何东西:) 任何时候你这样做都注定是一个糟糕的时刻。
  • @Idlehands Anytime you do is bound to be a bad time... 这是不正确的。将几何管理器分配给不会更新的小部件是非常好的,例如不需要在代码中稍后更新的标签和按钮,我认为将几何管理器分配给每个小部件的新行只是不必要的,并且没有充分的理由添加代码行。
  • 我不确定我是否遵循。 .pack()... 这样总是返回 None,不是吗?给这个结果命名有什么意义?确定几何管理器仍在执行,但分配的名称是无用的,肯定会像这种情况一样引起混乱?
  • @Idlehands 考虑了可读性。如果我有Button(root, text="go", command=go).pack(),以后阅读代码时可能不清楚该按钮在代码中的作用。但是,如果您使用login_button = Button(root, text="go", command=go).pack(),那么您清楚地知道此按钮的用途,并且不需要将其打包到新行中。
  • 很容易通过评论来补救,但我明白你的意思。我想只是不同的实现方式。我坚持我的立场,但我不会为那些认为这很有用的人辩护。每个人都有自己的:)
【解决方案2】:

在这种情况下您不需要两个框架,只需使用 grid 来对齐标签: columnrow 格式还使其更易于阅读,并且您还可以选择其他选项,例如 padxpadysticky,以获得更大的设计灵活性。

import tkinter as tk

root = tk.Tk()
frame = tk.Frame(root)
frame.grid()
root.title("Tkinter Window")  # Replace with anything else you want
label1 = tk.Label(root, text="Label1").grid(column=0,row=0)
label2= tk.Label(root,text="Label2").grid(column=0,row=1)
root.mainloop()

您可以了解更多关于gridhere的信息。

【讨论】:

  • OP 的问题包含第二帧是有原因的。为了这个问题,他们提供的示例是一个 MVCE,但我确信 OP 尝试在顶层窗口中使用框架是有充分理由的。
  • 感谢您的指出。我明白那个。但是,我刚刚分享了另一种获得相同结果的方法。我在尝试管理 tkinter 窗口中的多个项目时遇到了一些困难,那时我遇到了“网格”的做法。也许他不知道其他选择?
  • 好吧,在这种情况下,pack vs grid 不是问题,只是几何管理器分配顺序的问题。但是,我确实同意更喜欢使用网格。这是我的目标。
  • @Mike-SMT 在我的情况下,我需要为一个表单创建多行,我正在使用一个简单的 if 循环,所以我使用框架而不是网格来避免需要枚举if 循环并分配行号。这是可取的吗?
  • @NathanTew 你可以这样做,但老实说,如果你使用循环,那么你可以使用for ndex, item in list 来管理网格行。用网格来做这件事并不难,但这就是说,如果你想使用一个框架并且只是简单地将所有东西打包在那个框架中,它应该可以做你想做的事情并且可以正常工作。
猜你喜欢
  • 1970-01-01
  • 2021-04-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多