tkinter grid:在帧高和宽度上分配行和列

时间:2014-11-23 01:08:38

标签: python python-3.x tkinter grid

在Mac OS上使用python 3.4.1我试图在名为“lowerframe”的子帧中使用网格几何管理器同等地分发标签和条目小部件。

我目前的MWE如下所示:

#!/usr/bin/env python3

from tkinter import *
from tkinter import ttk

class Window(Frame):
    def __init__(self, master=None):
        Frame.__init__(self, master)
        # create master window
        self.master = master

        # create root window on initialization
        self.create_rootwindow()

    def create_rootwindow(self):
        self.master.title("GUI")
        self.master.geometry("1024x748")
        self.master.resizable(width=FALSE, height=FALSE)

        self.create_upperframe()
        self.create_lowerframe()
        self.create_inputentries()
        self.create_btnframe()
        self.create_inputbtn()

    def create_upperframe(self):
        self.upperframe = Frame(self.master, width=980, height=490)
        self.upperframe.config(background="#339900")
        self.upperframe.place(x=20, y=10)

    def create_lowerframe(self):
        self.lowerframe = Frame(self.master, width=830, height=200)
        self.lowerframe.config(background="#336699")
        self.lowerframe.place(x=20, y=530)

    def create_inputentries(self):
        self.create_lowerframe()

        parameternames = [
            ('a', 'U'), ('b', 'U'), ('c', 'U'), ('d', 'U'), ('e', 'U'),
            ('f', 'U'), ('g', 'U'), ('h', 'U'), ('i', 'U'), ('j', 'U'),
            ('k', 'U'), ('l', 'U'), ('m', 'U'), ('n', 'U'), ('o', 'U'),
            ('p', 'U'), ('q', 'U'), ('r', 'U'), ('s', 'U'), ('t', 'U')]

        for i, data in enumerate(parameternames):
            r = i % 5
            c = (i // 5) * 3
            Label(self.lowerframe, text=data[0]).grid(row=r, column=c, pady=4, padx=0)
            Entry(self.lowerframe, width=10).grid(row=r, column=c+1, pady=4, padx=0)
            Label(self.lowerframe, text=data[1]).grid(row=r, column=c+2, pady=4, padx=0)

    def create_btnframe(self):
        self.btnframe = Frame(self.master, width=130, height=200)
        self.btnframe.place(x=870, y=530)

    def create_inputbtn(self):
        self.create_btnframe()

        startanalysis_btn = Button(self.btnframe, text="Start Analysis", width=12, command=self.do_nothing)
        startanalysis_btn.place(x=0, y=0)

        abortanalysis_btn = Button(self.btnframe, text="Abort Analysis", width=12, command=self.do_nothing)
        abortanalysis_btn.place(x=0, y=50)

        resetanalysis_btn = Button(self.btnframe, text="Reset Analysis", width=12, command=self.do_nothing)
        resetanalysis_btn.place(x=0, y=100)

        showresults_btn = Button(self.btnframe, text="Show Results", width=12, command=self.do_nothing)
        showresults_btn.place(x=0, y=200, anchor=SW)

    def do_nothing(self):
        pass

root = Tk()

app = Window(root)

root.mainloop()

如您所见,较低的蓝色框架(称为“下框架”)中的每个“小组”小部件都包含带有描述的标签(此处为“a”到“t”),条目小部件和另一个标签具有输入值的相应单位的小部件(对于所有标签,此处为“U”)。

使用这些“集合”我需要创建五行和四个“设置列”(目前使用网格几何管理器的12列)。我的目标是将这些行和“设置列”分配到指定的下层高度和宽度。

- 编辑:我将sketch上传到我的Dropbox文件夹,显示结果应如何。

1 个答案:

答案 0 :(得分:2)

您编写代码的方式使得修改非常困难。首先,根据经验,你不应该使用place。根本没有必要,因为packgrid提供了更多功能。

其次,作为另一条经验法则,父母应负责布置其子女 - 没有创建框架的功能也可以调用gridpack或{{ 1}}将自己置于其父级中。如果你决定改变你的布局,你最终不得不改变一堆功能。

最后,当使用网格时,如果希望它们增长以填充其包含的窗口,则需要为行和列提供“权重”。

以下是重写代码的方法:

place

需要注意的事项:

  • 我已将from tkinter import * class Window(Frame): def __init__(self, master=None): Frame.__init__(self, master) # create master window self.master = master # create root window on initialization self.create_rootwindow() def create_rootwindow(self): self.master.title("GUI") self.master.geometry("1024x748") self.create_upperframe() self.create_lowerframe() self.create_inputentries() self.create_btnframe() self.create_inputbtn() self.upperframe.pack(side="top", fill="both", expand=True, padx=4) self.lowerframe.pack(side="left", fill="both", expand=True, padx=4, pady=4) self.btnframe.pack(side="right", fill="both", padx=4, pady=4) def create_upperframe(self): self.upperframe = Frame(self.master, width=980, height=490) self.upperframe.config(background="#339900") def create_lowerframe(self): self.lowerframe = Frame(self.master, width=830, height=200) self.lowerframe.config(background="#336699") def create_inputentries(self): self.create_lowerframe() parameternames = [ ('a', 'U'), ('b', 'U'), ('c', 'U'), ('d', 'U'), ('e', 'U'), ('f', 'U'), ('g', 'U'), ('h', 'U'), ('i', 'U'), ('j', 'U'), ('k', 'U'), ('l', 'U'), ('m', 'U'), ('n', 'U'), ('o', 'U'), ('p', 'U'), ('q', 'U'), ('r', 'U'), ('s', 'U'), ('t', 'U')] for i, data in enumerate(parameternames): r = i % 5 c = (i // 5) * 3 Label(self.lowerframe, text=data[0]).grid(row=r, column=c, pady=4, padx=0, sticky="nsew") Entry(self.lowerframe, width=10).grid(row=r, column=c+1, pady=4, padx=0, sticky="ew") Label(self.lowerframe, text=data[1]).grid(row=r, column=c+2, pady=4, padx=0, sticky="nswe") self.lowerframe.grid_columnconfigure(c+1, weight=1) def create_btnframe(self): self.btnframe = Frame(self.master, width=130, height=200) def create_inputbtn(self): self.create_btnframe() startanalysis_btn = Button(self.btnframe, text="Start Analysis", width=12, command=self.do_nothing) abortanalysis_btn = Button(self.btnframe, text="Abort Analysis", width=12, command=self.do_nothing) resetanalysis_btn = Button(self.btnframe, text="Reset Analysis", width=12, command=self.do_nothing) showresults_btn = Button(self.btnframe, text="Show Results", width=12, command=self.do_nothing) startanalysis_btn.pack(side="top", fill="x") abortanalysis_btn.pack(side="top", fill="x") resetanalysis_btn.pack(side="top", fill="x") showresults_btn.pack(side="top", fill="x") def do_nothing(self): pass root = Tk() app = Window(root) root.mainloop() 的所有用法替换为place(尽管pack也可以正常使用)
  • 我在创建主要区域后将grid分组在一起
  • 我将按钮的pack组合在一起,使其可视化和修改变得更容易
  • 我在底部框架中的入口小部件的列中添加了权重。这会导致这些列增长或缩小以填充任何额外的空间
  • 我删除了可调整大小为false的设置。一般来说,我认为应该允许用户选择GUI的大小。此外,它说明了使用pack和/或pack代替grid,您可以获得适当的调整大小行为而无需任何额外的努力。如果你真的认为你比用户更了解,你可以把它放回去。

代码现在具有良好的调整大小行为,条目小部件的网格扩展以填充其容器,并且函数不太紧密耦合,因为创建框架的函数不必知道该框架将如何显示。