使用网格布局管理器的默认行为是列尽可能小,因此您不需要做任何事情(假设您正确地使用了网格)。
您描述的行为,即元素之间有太多空间,可能是由于该列中还有其他更宽的小部件。该列将默认为能够容纳最宽项目的最小宽度。或者在您的代码中,在某些列上赋予非零权重,导致它们扩展。
在我讨论解决方案之前,让我确保清楚地说明,您使用网格将多个小部件放在同一单元格中的方式绝对是错误的。没有任何理由采用这种解决方案。一个经验法则是您永远不应该将多个小部件放入单元格中。
您的最简单解决方案是将grid和pack组合使用。将所有复选框放在一个框架中,并将其放置在该框架的左侧。然后,将该框架放入grid中,并使用sticky="w"
。然后,无论窗口变得多大,复选框始终会粘在其包含框架的左侧。
请注意,此解决方案不违反我之前提到的经验法则。您只在一个单元格中放置一个小部件:框架。您可以在该内部框架中放置任何内容,但从网格的角度来看,每个单元格中只有单个小部件。
以下是基于Python 2.7的工作示例:
import Tkinter as tk
class ExampleView(tk.Frame):
def __init__(self, *args, **kwargs):
tk.Frame.__init__(self, *args, **kwargs)
cbframe = tk.Frame(self)
cb1 = tk.Checkbutton(cbframe, text="Choice 1")
cb2 = tk.Checkbutton(cbframe, text="Choice 2")
cb3 = tk.Checkbutton(cbframe, text="Choice 3")
cb1.pack(side="left", fill=None, expand=False)
cb2.pack(side="left", fill=None, expand=False)
cb3.pack(side="left", fill=None, expand=False)
e1 = tk.Entry(self, width=20)
e1.grid(row=1, column=1, sticky="ew")
cbframe.grid(row=2, column=1, sticky="w")
self.grid_columnconfigure(1, weight=1)
if __name__ == "__main__":
root = tk.Tk()
view = ExampleView(root)
view.pack(side="top", fill="both", expand=True)
root.wm_geometry("400x200")
root.mainloop()
当然,您也可以将复选框放置在单独的列中 -- 这通常是最简单的方法 -- 但您可能需要让其他行中的其他项目跨越多列并处理列权重。由于根据您的描述不清楚您的问题是什么,因此上述解决方案可能对您来说是最简单的。