简体   繁体   English

使用tkinter的框架布局

[英]frames layout using tkinter

I'm playing with tkinter frames layout. 我在玩tkinter框架布局。 I got a great anwser from Bryan yestarday, unfortunetly I run into problem filling my frames. 昨天我从布莱恩(Bryan)那里得到了一个很好的答案,很不幸,我在填充框架时遇到了问题。 For some reason right upper frame is getting some extra space from the main frame and that breaks my layout, how can I prevent this from happening ? 出于某种原因,右上框架从主框架中获得了一些额外的空间,这破坏了我的布局,如何防止这种情况发生? its OK if the label_frame expands but I don't want it to get an extra space from the main frame. 如果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()

在此处输入图片说明

planned layout 计划的布局

在此处输入图片说明

The only problem is that you haven't given a weight to the row and the column that the label frame is in . 唯一的问题是您没有给标签框所在的行和列赋予权重。 You've given weights to the widgets in the label frame, but not weights to RightUpperWindow . 你给的权重,以标签帧的窗口小部件,而不是权重RightUpperWindow

Add this to RightUpperWindow.__create_layout 将此添加到RightUpperWindow.__create_layout

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

Every time you use grid in a container, you need to give at least one row and one column in that container a weight . 每次在容器中使用grid时,都需要给该容器中的至少一行和一列赋予weight This needs to be done for every container that is using grid to manage its children. 对于使用grid管理其子级的每个容器,都需要这样做。

Personally, if this were my code I'd use pack to put the labelframe inside of UpperRightWindow since it's the only window in that frame. 就个人而言,如果这是我的代码,我将使用pack将labelframe放在UpperRightWindow内,因为它是该帧中的唯一窗口。 With pack yo don't have to use extra lines to add weights to rows and columns. 使用pack yo不必使用多余的行来增加行和列的权重。 There's nothing wrong with mixing grid and pack in the same application, as long as you use them in different frames. 只要在不同的框架中使用gridpack ,就可以在同一应用程序中混合使用gridpack

The above fixes the problem that the inner labelframe wasn't expanding to fill the space given to it. 上面的方法解决了内部标签框架无法扩展以填充指定空间的问题。 You also have the problem that the wrong widgets inside the label frame are expanding. 您还存在一个问题,即标签框架的错误小部件正在扩展。

You're currently giving a weight to row and column 0 inside the labelframe, which will not give you the expected output. 您目前正在为labelframe内的行和列0赋予权重,这不会给您预期的输出。 Since you want all of the rows to be a uniform height, give the row below the last widget a weight so that it takes up all the extra space. 由于您希望所有行都具有统一的高度,因此请为最后一个小部件下方的行赋予权重,以使其占用所有额外空间。 Also, you probably want to give column one a weight, since it makes more sense to grow and shrink the input field rather than the label. 另外,您可能希望赋予第一列权重,因为增大和缩小输入字段(而不是标签)更有意义。

Change this: 更改此:

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

... to this: ...对此:

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

You appear to be adding all the text/entry labels to self.label_frame, which is placed on row 0 column 8 of your main frame. 您似乎正在将所有文本/条目标签添加到self.label_frame中,该标签位于主框架的第0行第8列。 I assume you want to use the 4 rows and 2 columns allocated to the upper right window for these labels and entries? 我假设您要使用分配给右上角窗口的4行2列用于这些标签和条目? If that case there is no need to use label_frame. 如果是这种情况,则无需使用label_frame。 Try something like this instead: 尝试这样的事情:

#
# 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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM