Python - 使用网格布局格式化窗口

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python - 使用网格布局格式化窗口相关的知识,希望对你有一定的参考价值。

我正在教自己Python并尝试构建一个使用窗口GUI的本地应用程序。我在尝试使用grid()布局屏幕时遇到了很多麻烦。我搜索并尝试了许多不同的代码片段,但我有同样的问题,框架和小部件似乎不是格式化。下面的代码非常简单,但我的最终目标是掌握如何使用grid(),以便我可以构建我喜欢的任何GUI。

我希望能够做到以下几点:

--Window-----------------
| Section 1 | Section 2 |
|           |           |
-------------------------
| Section 3             |
|                       |
|                       |
-------------------------

from Tkinter import Button, Frame, Entry, Tk, Label, Menubutton, Menu, IntVar

class MainScreen(Frame):
def __init__(self, master):
    Frame.__init__(self, master)
    self.grid()
    self.searchSection()
    self.quitButton()


def searchSection(self):
    # Create Search Section
    self.searchFrame = Frame(self.master, bg='grey', relief='sunken', width=200, height=200)
    self.searchFrame.grid(row=0, column=0, rowspan=5, columnspan=30, sticky="wens")
    Label(self.searchFrame, text="Search :", bg='grey').grid(row=1, column=1, columnspan=20, sticky='w')
    self.searchField = Entry(self.searchFrame)
    self.searchField.grid(row=2, column=1, columnspan=7, sticky='w')
    #Create Menu Options
    self.search = Menubutton(self.searchFrame, text = "Search", bg='grey')
    self.search.grid(row=2, column=8, columnspan=3, sticky='w')
    self.search.menu = Menu(self.search, tearoff = 0)
    self.search['menu'] = self.search.menu       
    self.SearchType1Var = IntVar()
    self.search.menu.add_checkbutton(label="SearchType1", variable = self.SearchType1Var)


def quitButton(self):
    ## Provide a quit button to exit the rogram
    self.quitFrame = Frame(self.master, bg='grey', width=50, height=50)
    self.quitFrame.grid(row=0, column=20, rowspan=5, columnspan=5, sticky='ewns')
    self.quitButton = Button(self.quitFrame, text="Quit", command=exit)
    self.quitButton.grid()


if __name__ == '__main__':

root = Tk()
root.title("Learn Grid GUI")
root.geometry("800x600+200+150")
main = MainScreen(root)
root.mainloop()
答案

你使用子帧的直觉很好,但你的实现使得问题比应该更难。根据一般的经验法则,我建议不要使用不同的函数来创建小部件并将它们放在父级中。换句话说,给定容器的所有gridpack语句通常都应该在同一个函数中。

根据我的经验,完成布局的最佳方式是“分而治之”。例如,您的ascii绘图显示了三个部分。从那开始,只有那个。创建三个框架,每个部分一个。在尝试向其添加任何内容之前,将它们正确放置在容器中。

当我这样做时,我首先给每个帧一个明确的颜色和一个明确的大小只是为了可视化目的。例如:

import Tkinter as tk

class Example(tk.Frame):
    def __init__(self, master, *args, **kwargs):
        tk.Frame.__init__(self, master, *args, **kwargs)
        self.master = master
        self.s1 = tk.Frame(self, background="pink", width=200, height=200)
        self.s2 = tk.Frame(self, background="blue", width=200, height=200)
        self.s3 = tk.Frame(self, background="bisque", width=200, height=200)

        self.s1.grid(row=0, column=0, sticky="nsew")
        self.s2.grid(row=0, column=1, sticky="nsew")
        self.s3.grid(row=1, column=0, columnspan=2, sticky="nsew")

        self.grid_rowconfigure(0, weight=1)
        self.grid_columnconfigure(1, weight=1)

if __name__ == "__main__":
    root = tk.Tk()
    Example(root).pack(side="top", fill="both", expand=True)
    root.mainloop()

一旦我正常工作并正确调整大小,我就可以继续添加小部件,一次一个部分。由于我已经让GUI的主要部分适当地响应窗口调整大小,我可以将所有精力集中在一个部分,而不用担心它们如何影响程序的其余部分。

重要的是要知道,当您向其中一个部分添加小部件时,该部分中的行和列独立于任何其他小部件。例如,如果您在第2部分的第1列中添加了某些内容,那么它将引用第2部分中的第1列,而不是整个GUI的绝对列。

为了便于说明,我们假设您希望搜索标签,条目小部件和菜单按钮全部放在第3部分中(我无法从您的问题中找出您希望它们去的地方)。在这种情况下,标签位于第0行并跨越两列,条目小部件和menubutton位于不同的列中。我假设您希望第一列增长和缩小。

这需要对程序进行两次修改。第一个是创建searchSection函数,它在搜索部分创建小部件。第二个修改是在GUI的构造函数中调用此函数。

这是一个完全正常的最终版本:

import Tkinter as tk

class Example(tk.Frame):
    def __init__(self, master, *args, **kwargs):
        tk.Frame.__init__(self, master, *args, **kwargs)

        self.s1 = tk.Frame(self, background="pink", width=200, height=200)
        self.s2 = tk.Frame(self, background="blue", width=200, height=200)
        self.s3 = tk.Frame(self, background="bisque", width=200, height=200)

        self.s1.grid(row=0, column=0, sticky="nsew")
        self.s2.grid(row=0, column=1, sticky="nsew")
        self.s3.grid(row=1, column=0, columnspan=2, sticky="nsew")

        self.grid_rowconfigure(0, weight=1)
        self.grid_columnconfigure(1, weight=1)

        # now create the search section
        self.searchSection(self.s1)

    def searchSection(self, parent):
        l = tk.Label(parent, text="Search :", bg='grey')
        self.searchField = tk.Entry(parent)
        self.search = tk.Menubutton(parent, text="Search", bg="grey")
        self.search.menu = tk.Menu(self.search, tearoff = 0)
        self.search['menu'] = self.search.menu
        self.SearchType1Var = tk.IntVar()
        self.search.menu.add_checkbutton(label="SearchType1", 
                                         variable = self.SearchType1Var)

        l.grid(row=0, column=0, columnspan=2, sticky='w')
        self.searchField.grid(row=1, column=0, sticky="ew")
        self.search.grid(row=1, column=1, sticky="ew")

        parent.grid_columnconfigure(0, weight=1)

if __name__ == "__main__":
    root = tk.Tk()
    Example(root).pack(side="top", fill="both", expand=True)
    root.mainloop()
另一答案

如果我理解正确,你的问题是你无法对GUI进行排序。答案非常简单 - 如果您想对GUI进行排序,只需将代码放在您希望窗口显示的顺序中。例如:

 --Window--
| text box |
|  button  |
|          |
------------

-Code-
[text box code here]
[button code here]
root.mainloop()

我已经和tkinter合作了很长时间,它对我有用。祝你好运,节日快乐!

LStyle

以上是关于Python - 使用网格布局格式化窗口的主要内容,如果未能解决你的问题,请参考以下文章

使用属性窗口在 QT 网格布局中设置小部件的行和列

如何在kotlin的片段内显示网格视图?

MFC 网格是绝对布局,在调整窗口大小时会被剪裁

python之tkinter使用-Grid(网格)布局管理器

PyQt4网格布局

如何使用具有绝对布局的框架在网格顶部创建弹出窗口?