Tkinter网格:在框架高度和宽度上分布行和列

2024-09-29 06:32:45 发布

您现在位置:Python中文网/ 问答频道 /正文

在macos上使用python3.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()

如您所见,下部蓝色框架(称为“lowerframe”)中的每个“集合”小部件都由一个带有描述的标签(这里是“a”到“t”)、一个条目小部件和另一个具有相应输入值单位的标签小部件(此处为“U”表示所有标签)。在

使用这些“集合”,我需要创建5行和4个“集合列”(目前使用网格几何管理器的12列)。我的目标是将这些行和“设置列”分布到指定的lowerframe的高度和宽度。在

--编辑:我上传了一个sketch到我的Dropbox文件夹,显示结果应该是什么样子。在


Tags: textselfmasterdefcreateplace标签width
1条回答
网友
1楼 · 发布于 2024-09-29 06:32:45

您编写代码的方式使其很难修改。首先,根据经验,你不应该使用place。根本没有必要,因为pack和{}提供了更多的功能。在

其次,作为另一条经验法则,父对象应该负责安排它的子对象没有一个创建框架的函数,也就是调用gridpack、或{}来将自己放入其父对象中。如果你决定改变你的布局,你最终不得不改变一堆功能而不是一个。在

最后,使用网格时,如果希望行和列增长以填充其包含的窗口,则需要给行和列赋予“权重”。在

下面是我如何重写你的代码:

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组合在一起
  • {I>可以说,将cd2>组合在一起更容易修改
  • 我为底部框架中有条目小部件的列添加了一个权重。这会导致这些列增长或收缩以填充任何额外的空间
  • 我删除了可调整大小设置为false。一般来说,我认为应该允许用户选择GUI的大小。另外,它还说明了通过使用pack和/或{}代替place,您可以在不需要任何额外努力的情况下获得正确的调整大小行为。如果你真的认为你比你的用户更了解,你可以把它放回去。在

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

相关问题 更多 >