什么是比.grid()更好的Tkinter几何管理器

xxm*_*exx 5 python tkinter

我的抱怨

我目前正在深入研究Tkinter GUI之前的"永远",我发现.grid()几何管理器不足以出于以下几个原因:

  1. 这些图基于其中最大的小部件 - 这种相对性导致不准确.

  2. 在Windows 7中,在Python 2.7.3上,程序似乎没有注意我的行号,而是更喜欢使用小部件的顺序.

我的守则

我目前正在开发一个非常基本的文本编辑器,我想在框架的顶部有多个按钮.我无法做到这一点,因为我的小部件被放置在占据屏幕中心的大型文本框的最左侧或右侧.

========Class __init__ Stuff============
def widget(self):#Place widgets here

    #Save Button
    self.saveButton = Button (self, text = "Save", command = self.saveMe)
    self.saveButton.grid(column = 0, row = 0, sticky = W)

    #Open Button
    self.openButton = Button (self, text = "Open", command = self.openMe)
    self.openButton.grid(column = 0, row = 1, sticky = W)
    #Area where you write 
    self.text = Text (self, width = (root.winfo_screenwidth() - 20),
                      height = (root.winfo_screenheight() - 10))
    self.text.grid(row = 2)
==============Mainloop/Command Stuff============
Run Code Online (Sandbox Code Playgroud)

我的问题

是否有另一种方式以.grid()更准确的方式使用几何管理器,或者我应该完全使用其他功能?

谢谢!

mgi*_*son 15

还有,你必须提供给您3名几何经理- grid,packplace.第三是最普遍的,但也很难使用.我更喜欢grid.请注意,您可以将小部件放在其他小部件中 - 或者您可以指定columnspan.所以,如果你想获得以下布局:

  -------------------------
  |    Button1  | Button2 |
  -------------------------
  |     Big Widget        |
  -------------------------
Run Code Online (Sandbox Code Playgroud)

有两种规范方法可以使用它.grid.第一种方法是columnspan:

import Tkinter as Tk
root = Tk.Tk()
b1 = Tk.Button(root,text="Button1")
b1.grid(row=0,column=0)
b2 = Tk.Button(root,text="Button2")
b2.grid(row=0,column=1)
big_widget = Tk.Canvas(root)
big_widget.grid(row=1,column=0,columnspan=2)
Run Code Online (Sandbox Code Playgroud)

*请注意,还有一个完全类似的rowspan选项.

第二种方法是使用a Frame来按住按钮:

import Tkinter as Tk
root = Tk.Tk()
f = Tk.Frame(root)
f.grid(row=0,column=0)
#place buttons on the *frame*
b1 = Tk.Button(f,text="Button1")
b1.grid(row=0,column=0)
b2 = Tk.Button(f,text="Button2")
b2.grid(row=0,column=1)

big_widget = Tk.Canvas(root)
big_widget.grid(row=1,column=0)  #don't need columnspan any more.
Run Code Online (Sandbox Code Playgroud)

这种方法是SUPER创建复杂的布局非常有用-我不知道你怎么可以不使用创建一个复杂的布局Frame像这样的对象...

  • 至于如何使用OOP来做 - 我不知道.我不会过分关注使用OOP或不使用OOP.我只是尝试让代码以对我有意义的方式工作,并尽可能地清理界面.坐下来弄清楚你希望这些部分如何交互真的很值得 - 然后,一旦你弄清楚如何在程序中传递数据,通常就可以更容易地设计GUI.我认为你可以使用`Tkinter`来做更大的项目.我知道布莱恩奥克利会同意 - 但其他人会不同意.较大的项目通常使用gtk/wxWidgets. (2认同)

Bry*_*ley 5

"最佳"几何管理器取决于您想要做什么,没有几何管理器最适合所有情况.对于您在此特定情况下尝试做的事情,打包可能是更好的选择.另请注意,应用程序中可能有多个"最佳".在应用程序的不同部分使用网格和包是很正常的.我很少创建一个GUI,我不使用网格和包.很少,我也使用地方.

pack擅长将东西放在单行和单列中.例如,工具栏是使用pack的理想选择,因为您希望所有按钮都对齐到左侧.顾名思义,网格最适合您想要固定的行和列.在网格和包都不会发生的极少数情况下,place非常有用,因为它允许您将小部件放在精确的固定或相对位置.

我的建议是将应用程序小部件分成组,并为每个组使用正确的几何管理器.在您的情况下,您有两个逻辑组:顶部的工具栏,以及底部的文本小部件和滚动条组合.所以,从两帧开始.由于工具栏位于顶部,文本小部件位于下方,因此打包效果最佳.

toolbar = tk.Frame(...)
main = tk.Frame(...)
toolbar.pack(side="top", fill="x", expand=False)
main.pack(side="bottom", fill="both", expand=True)
Run Code Online (Sandbox Code Playgroud)

以上现在为您提供了两个易于独立修改的区域.

对于工具栏,包装也是最自然的.但是,在这种情况下,您需要左侧的按钮而不是顶部或底部的按钮:

b1 = tk.Button(toolbar, ...)
b2 = tk.Button(toolbar, ...)
b1.pack(side="left")
b2.pack(side="left")
...
Run Code Online (Sandbox Code Playgroud)

最后,底部区域.您的示例代码不显示滚动条,但我认为在某些时候您会想要添加它们.如果您同时使用水平和垂直滚动条,网格效果很好.我会这样说出来:

hsb = tk.Scrollbar(main, ..., orient="horizontal", ...)
vsb = tk.Scrollbar(main, ..., orient="vertical", ...)
text = tk.Text(main, ...)
vsb.grid(row=0, column=1, sticky="ns")
hsb.grid(row=1, column=0, sticky="ew")
text.grid(row=0, column=0, sticky="nsew")
main.grid_rowconfigure(0, weight=1)
main.grid_columnconfigure(0, weight=1)
Run Code Online (Sandbox Code Playgroud)

最后一部分很重要 - 你总是需要给至少一行和一列赋予权重.这会告诉网格调整窗口大小时哪些行和列应该增长和缩小.