1

我正在自学 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()
4

2 回答 2

2

您使用子帧的直觉很好,但是您的实施使问题变得比应有的困难。对于一般的经验法则,我建议不要让不同的函数创建小部件并将它们放在它们的父级中。换句话说,给定容器grid的所有orpack语句通常都应该在同一个函数中。

根据我的经验,完成布局的最佳方式是“分而治之”。例如,您的 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 部分的第一列中放置一些内容,则它指的是第二部分中的第一列,而不是整个 GUI 的绝对列。

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

这需要对程序进行两次修改。首先是创建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()
于 2013-03-25T16:19:36.767 回答
0

如果我理解正确,您的问题是您无法对 GUI 进行排序。答案很简单——如果您想对 GUI 进行排序,只需将代码按照您希望窗口显示的顺序放置即可。例如:

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

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

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

L型

于 2013-03-24T11:00:07.107 回答