7

我的投诉

我目前比以往任何时候都更深入地研究 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============

我的问题

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

谢谢!

4

4 回答 4

16

您可以使用 3 个几何管理器-grid和。第三种是最通用的,但也非常难用。我更喜欢. 请注意,您可以将小部件放置在其他小部件中 - 或者您可以指定. 因此,如果您想获得以下布局:packplacegridcolumnspan

  -------------------------
  |    Button1  | Button2 |
  -------------------------
  |     Big Widget        |
  -------------------------

有 2 种规范的方法可以使用.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)

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

第二种方法是使用 aFrame来按住你的按钮:

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.

这种方法对于创建复杂的布局非常有用——我不知道如何在不使用这样的Frame对象的情况下创建复杂的布局......

于 2013-02-13T03:54:52.077 回答
7

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

pack 擅长将东西放在单行和单列中。例如,工具栏是使用 pack 的完美案例,因为您希望所有按钮都向左对齐。顾名思义,当您需要固定的行和列时,网格是最好的。place 在 grid 和 pack 都不会做的极少数情况下很有用,因为它允许您将小部件放置在精确的固定或相对位置。

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

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

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

对于工具栏,pack 再次是最自然的。但是,在这种情况下,您希望按钮位于左侧而不是顶部或底部:

b1 = tk.Button(toolbar, ...)
b2 = tk.Button(toolbar, ...)
b1.pack(side="left")
b2.pack(side="left")
...

最后是底部区域。您的示例代码不显示滚动条,但我假设在某些时候您会想要添加它们。如果您同时使用水平和垂直滚动条,grid 效果很好。我会这样布置它们:

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)

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

于 2013-02-13T12:24:14.193 回答
1

我发现place经理是所有三个中最直观和准确的,因为可以为位置和大小指定绝对和相对长度的组合:

mywidget.place(x=..., y=..., width=..., height=...) # absolute
mywidget.place(relx=..., rely=..., relwidth=..., relheight=...) # relative

# combination
pad_left=5
pad_right=5
pad_top=5
pad_bottom=5
mywidget.place(relx=0, x=pad_left, rely=0, y=pad_top,\
       relwidth=1, width=-pad_left-pad_right,\
       relheight=1, height=-pad_top-pad_bottom, anchor="e") # use the whole space except some padding

出于某种原因,.place管理器似乎不太受欢迎,但我发现定义小部件在调整父窗口大小时应该如何移动和调整大小是一项特别好的工作。

为了简化复杂窗口的构建,我有时会使用一个函数(模拟我想的网格行为)来帮助垂直放置,例如:

def offset_y(line_no):
    if line_no == 0:
        return 0
    else:
        return height_label + (line_no - 1)*height_button

mylabel.place(..., y=offset_y(0))
mybtn1.place(..., y=offset_y(1))
etc.

垂直包装一个标签,然后是一系列按钮。(当然,.pack在这种情况下可以使用管理器,但我更喜欢.place管理器的原因是为了更准确地了解调整窗口大小时事物将如何移动)。

于 2013-04-06T15:32:33.693 回答
-2

您可以使用坐标来代替行、列...等。

它可能比其他人更容易。

例子:

from Tkinter import*
root=Tk()
Button(root,text="HI").grid(padx=100,pady=50)
root.mainloop()

通过更改 padx 和 pady 值自己尝试一下。

于 2017-03-10T07:16:20.730 回答