我正在教自己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()
答案 0 :(得分:2)
您使用子帧的直觉很好,但是您的实施会使问题变得更加困难。根据一般的经验法则,我建议反对使用不同的函数创建小部件并将它们放在父级中。换句话说,给定容器的所有grid
或pack
语句通常都应该在同一个函数中。
根据我的经验,完成布局的最佳方法是“分而治之”。例如,您的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列中添加了某些内容,那么第1部分中的第1列 第2部分,而不是整个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()
答案 1 :(得分:0)
如果我理解正确,您的问题是您无法对GUI进行排序。 答案非常简单 - 如果您想对GUI进行排序,只需将代码放在您希望窗口显示的顺序中。例如:
--Window--
| text box |
| button |
| |
------------
-Code-
[text box code here]
[button code here]
root.mainloop()
我已经和tkinter合作了很长时间,它对我有用。 祝你好运,庆祝圣日快乐!
LStyle