【问题标题】:Quick Tkinter Formatting Issue快速 Tkinter 格式问题
【发布时间】:2012-07-16 17:06:51
【问题描述】:

我有一堆这样的框架:

    +--+
    |  |
  +-+--+-+
  |      |
+-+------+-+
|          |
+----------+

但我希望它们是这样的:

        +--+
        |  |
    +---+--+
    |      |
+---+------+
|          |
+----------+

最好的方法是什么?

正在使用 pack,但无法让它们正常运行。由于某种原因,使用网格根本没有显示它们,我的程序挂起

# Main script
root = Tk()
root.geometry('500x500')
for task in TaskList:
    GuiTools.TaskBox.TaskBox(root, task)
root.mainloop() # program hangs from this line, to the point of having to use kill to close it



# Taskbox class
class Taskbox(master, task):
    __init__(self)
        self.TaskFrame = Frame(master, borderwidth=3, relief=RAISED)
         . . .
        Putting stuff in frame
         . . .
        self.TaskFrame.pack() # Gives result 1
        #self.TaskFrame.grid(column=1, sticky='ne') # no display, causes hang

【问题讨论】:

  • 如果您将小部件附加到特定框架或顶层,请使用全部pack 或全部grid。否则,tk 会很高兴地为您的小部件找出合适的位置,直到永远。
  • @mgilson 我认为这可能是正在发生的事情。我使用 pack 将框架收缩包装到其中一个组件上,这样我就可以实现我正在处理的一些其他功能。当我把网格放在那里时,这会导致挂起。
  • 可能。我对pack 了解不多,因为我从不使用它(这对我来说很反直觉,但有些人似乎经常使用它......)。
  • 明确一点:您可以在同一个应用程序中使用 pack 和 grid,但不能在同一个容器小部件中同时使用。

标签: python tkinter


【解决方案1】:

你几乎拥有它。在将小部件添加到窗口之前,您正在启动 mainloop,这将导致在 mainloop 完成之前不会添加它们。当主循环结束时,窗口不再可用,所以添加它们会失败。

这是一个简单的示例,显示 3 个框架按照您的要求相互叠加:

import Tkinter

root = Tkinter.Tk()
frame_one = Tkinter.Frame(root, width="50", height="50", borderwidth=3, relief=Tkinter.RAISED)
frame_one.grid(row=0, column=0, sticky=Tkinter.E)

frame_two = Tkinter.Frame(root, width="100", height="100", borderwidth=3, relief=Tkinter.RAISED)
frame_two.grid(row=1, column=0, sticky=Tkinter.E)

frame_three = Tkinter.Frame(root, width="150", height="150", borderwidth=3, relief=Tkinter.RAISED)
frame_three.grid(row=2, column=0, sticky=Tkinter.E)

root.mainloop()

【讨论】:

  • 请不要告诉 OP 创建一个框架,然后将其全部排成一行。现在你没有(容易)处理你创建的帧,因为.grid 返回None。实际使用您刚刚创建的框架的唯一方法是以某种方式将它们从root 中拉出(可能通过root.children 明确地整理出框架并以某种方式找出您想要的框架......)。这充其量是混乱的。
  • 我完全同意,为了一个简短的例子,我在同一条线上进行了网格划分。我现在就编辑它。
  • @mgilson。 OP 应该能够将其分开以满足他的需要。这只是一个展示如何完成的玩具示例。
  • @sc0tt 所有添加到框架的东西都可以正常工作。这些是 2 个不同的文件,我只是在这里一起运行它们,所以它们是可读的。试图用 cmets 来表示。我会使用建议的方法,除了我有一个可变长度的传入列表,所以我不能单独声明每个帧
  • @StevenRumbalski -- 通常我同意这一点,但这是我过去看到人们遇到问题的地方。如果不认识Tkinter 的人偶然发现了这篇文章,那么他们会认为 tk.Widget().grid()` 是事情的完成方式,当事情破裂时会造成更多的混乱。 SO 答案不仅适用于 OP,也适用于整个社区,因此我认为它们应该在适当的时候作为对良好实践的参考。
【解决方案2】:

在不知道您首先将什么放入框架的情况下回答这个问题有点棘手。 @sc0tt 是正确的,您可能想使用 sticky=tk.E,但是,这可能不足以获得您想要的东西,因为您的框架可能会根据您放入的内容调整自己的大小(除非您使用 myframe.grid_propagate(False))。解决这个问题的方法是同时输入columnspan 关键字。

这是一个愚蠢的循环,它会做你想做的事情:

import Tkinter as tk
root = tk.Tk()
frames = []
for i in range(3):
    f = tk.Frame(root)
    f.grid(row=i, column=0, columnspan=i+1, sticky=tk.E)
    frames.append(f)

#Now, you can add buffer spaces (frames) into the grid at 
# `row=0,column=0`, `row=0,column=1` and `row=1,column=1` if you need it. 

root.mainloop()

这样可以有效地划分您的网格:

+----+-----+-----+
|    |     |     |
+----+-----+-----+
|    |           |
+----+-----------+
|                |
+----------------+

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-09
    • 1970-01-01
    相关资源
    最近更新 更多