【问题标题】:frames layout using tkinter使用 tkinter 的框架布局
【发布时间】:2015-11-06 23:24:39
【问题描述】:

我正在玩 tkinter 框架布局。昨天我从 Bryan 那里得到了一个很好的答案,不幸的是我在填充我的框架时遇到了问题。出于某种原因,右上框架从主框架获得了一些额外的空间,这破坏了我的布局,我该如何防止这种情况发生?如果 label_frame 扩展就可以了,但我不希望它从主框架中获得额外的空间。

import sys
import os

import Tkinter as tk
import ttk as ttk

#
# Right Window
#
class RightUpperWindow(tk.Frame):
    def __init__(self, master=None):
        self.parent = master
        tk.Frame.__init__(self, self.parent, bg='bisque', borderwidth=0, relief="sunken")
        self.__create_layout()

    def __create_layout(self):

        self.label_frame = tk.LabelFrame(self, text="I'm a Label frame", padx=0, pady=0, borderwidth=0, width = 1)

        self.label1=tk.Label(self.label_frame, text="text1")
        self.label2=tk.Label(self.label_frame, text="text2")
        self.label3=tk.Label(self.label_frame, text="text3")

        self.entry1 = tk.Entry(self.label_frame)
        self.entry2 = tk.Entry(self.label_frame)
        self.entry3 = tk.Entry(self.label_frame)

        self.label_frame.grid(row=0, column=0, sticky=(tk.N, tk.S, tk.W, tk.E))

        self.label1.grid(row=0, column=0, sticky=(tk.N, tk.S, tk.W, tk.E))
        self.label2.grid(row=1, column=0, sticky=(tk.N, tk.S, tk.W, tk.E))
        self.label3.grid(row=2, column=0, sticky=(tk.N, tk.S, tk.W, tk.E))

        self.entry1.grid(row = 0, column = 1, sticky=(tk.N, tk.S, tk.W, tk.E))
        self.entry2.grid(row = 1, column = 1, sticky=(tk.N, tk.S, tk.W, tk.E))
        self.entry3.grid(row = 2, column = 1, sticky=(tk.N, tk.S, tk.W, tk.E))

        self.label_frame.columnconfigure(0, weight=1)
        self.label_frame.rowconfigure(0, weight=1)

#
# MainWindow
#
class MainWindow(tk.Frame):
    def __init__(self, master=None):
        self.parent = master
        tk.Frame.__init__(self, self.parent, bg='bisque', borderwidth=1, relief="sunken")
        self.__create_layout()

    def __create_layout(self):
        self.frame1 = tk.Frame(self, bg="grey")
        self.frame2 = RightUpperWindow(self) #tk.Frame(self, bg="blue")
        self.frame3 = tk.Frame(self, bg="green")
        self.frame4 = tk.Frame(self, bg="brown")
        self.frame5 = tk.Frame(self, bg="pink")

        self.frame1.grid(row=0, column=0, rowspan=4, columnspan=8, sticky=(tk.N, tk.S, tk.W, tk.E))
        self.frame2.grid(row=0, column=8, rowspan=4, columnspan=2, sticky=(tk.N, tk.S, tk.W, tk.E))
        self.frame3.grid(row=4, column=0, rowspan=2, columnspan=5, sticky=(tk.N, tk.S, tk.W, tk.E))
        self.frame4.grid(row=4, column=5, rowspan=2, columnspan=5, sticky=(tk.N, tk.S, tk.W, tk.E))
        self.frame5.grid(row=5, column=0, rowspan=1, columnspan=10, sticky=(tk.N, tk.S, tk.W, tk.E))

        for r in range(6):
            self.rowconfigure(r, weight=1)
        for c in range(10):
            self.columnconfigure(c, weight=1)

#
#   MAIN
#
def main():
    root = tk.Tk()

    root.title("Frames")
    root.geometry("550x300+525+300")

    root.configure(background="#808080")
    root.option_add("*font", ("Courier New", 9, "normal"))

    window = MainWindow(master=root)
    window.pack(side="top", fill="both", expand=True)
    root.mainloop()

if __name__ == '__main__':
    main()

规划布局

【问题讨论】:

  • 第二张图是我的规划布局

标签: python tkinter


【解决方案1】:

唯一的问题是您没有为标签框所在的行和列赋予权重。您已为标签框架的小部件赋予权重,但未赋予RightUpperWindow 权重。

将此添加到RightUpperWindow.__create_layout

self.rowconfigure(0, weight=1)
self.columnconfigure(0, weight=1)

每次在容器中使用grid 时,都需要为该容器中的至少一行和一列指定weight。这需要对使用grid 管理其子级的每个容器进行。

就个人而言,如果这是我的代码,我会使用pack 将标签框放在UpperRightWindow 内,因为它是该框架中唯一的窗口。使用pack,您不必使用额外的行来为行和列添加权重。在同一个应用程序中混合gridpack 并没有错,只要在不同的帧中使用它们即可。

以上解决了内部标签框没有扩展以填充给它的空间的问题。您还遇到标签框架内部扩展错误的小部件的问题。

您目前正在为标签框中的第 0 行和第 0 列赋予权重,这不会为您提供预期的输出。由于您希望所有行都具有统一的高度,因此为最后一个小部件下方的行赋予权重,以便它占用所有额外空间。此外,您可能希望为第一列赋予权重,因为扩大和缩小输入字段而不是标签更有意义。

改变这个:

    self.label_frame.columnconfigure(0, weight=1)
    self.label_frame.rowconfigure(0, weight=1)

...到这个:

    self.label_frame.columnconfigure(1, weight=1)
    self.label_frame.rowconfigure(3, weight=1)

【讨论】:

  • 我为你鼓掌,先生,脱帽致敬!
  • 也许我会按照你的建议使用包布局。我已将我的包布局代码添加到问题中,但为什么它不扩展条目?
  • @krusty:在你已经得到答案之后如此剧烈地改变代码会让人们非常困惑。我很想删除我的答案,因为修改后的代码意义不大。另外,您似乎误解了我的言论。我不建议在 labelframe 中使用 pack inside,仅用于 labelframe 本身。
  • 抱歉,Bryan,我删除了我添加的包中的错误代码。
【解决方案2】:

您似乎正在将所有文本/条目标签添加到 self.label_frame,该标签位于主框架的第 0 行第 8 列。我假设您想为这些标签和条目使用分配给右上方窗口的 4 行和 2 列?如果这种情况没有必要使用 label_frame。 试试这样的:

#
# Right Window
#
class RightUpperWindow(tk.Frame):
    def __init__(self, master=None):
        self.parent = master
        tk.Frame.__init__(self, self.parent, bg='bisque', borderwidth=0, relief="sunken")
        self.__create_layout()

    def __create_layout(self):

        # self.label_frame = tk.LabelFrame(self, text="I'm a Label frame", padx=0, pady=0, borderwidth=0, width = 1)
        self.label0=tk.Label(self, text="header")
        self.label1=tk.Label(self, text="text1")
        self.label2=tk.Label(self, text="text2")
        self.label3=tk.Label(self, text="text3")

        self.entry1 = tk.Entry(self)
        self.entry2 = tk.Entry(self)
        self.entry3 = tk.Entry(self)

        # self.label_frame.grid(row=0, column=0, sticky=(tk.N, tk.S, tk.W, tk.E))
        self.label0.grid(row=0, column=0, columnspan=2, sticky=(tk.N, tk.S, tk.W, tk.E))
        self.label1.grid(row=1, column=0, sticky=(tk.N, tk.S, tk.W, tk.E))
        self.label2.grid(row=2, column=0, sticky=(tk.N, tk.S, tk.W, tk.E))
        self.label3.grid(row=3, column=0, sticky=(tk.N, tk.S, tk.W, tk.E))

        self.entry1.grid(row = 1, column = 1, sticky=(tk.N, tk.S, tk.W, tk.E))
        self.entry2.grid(row = 2, column = 1, sticky=(tk.N, tk.S, tk.W, tk.E))
        self.entry3.grid(row = 3, column = 1, sticky=(tk.N, tk.S, tk.W, tk.E))

        self.columnconfigure(0, weight=1)
        self.rowconfigure(0, weight=1)

【讨论】:

  • 谢谢,但不,这不是它。我添加了一张图片来显示我想要的布局。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-10-18
  • 2012-11-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-07
相关资源
最近更新 更多