Python Tkinter网格几何粘贴设置无效(?)

5 投票
1 回答
7350 浏览
提问于 2025-04-17 19:46

我正在用Python/Tkinter设计一个简单的输入对话框,使用的是grid布局,但遇到了一些意想不到的情况。当我开始写这段代码时:

winAddNew = tk.Toplevel()
winAddNew.title('Add New Customer')
lblName = tk.Label(winAddNew,
                   anchor=tk.W,font=fntNormal,
                   text='Enter the complete name of the customer:')
entName = tk.Entry(winAddNew,
                   justify=tk.LEFT, font=fntNormal, width=20,
                   textvariable=ctrlNewCustomerName)
lblID = tk.Label(winAddNew,
                 anchor=tk.W,font=fntNormal,
                 text='Enter a unique three-character ID:')
entID = tk.Entry(winAddNew,
                 justify=tk.LEFT, font=fntNormal, width=8,
                 textvariable=ctrlNewCustomerID)
lblName.grid(row=0,column=0,columnspan=2,sticky=tk.W,padx=10,pady=(10,0))
entName.grid(row=1,column=0,columnspan=2,sticky=tk.W,padx=10,pady=(5,0))
lblID.grid(row=2,column=0,sticky=tk.W,padx=(10,0),pady=10)
entID.grid(row=2,column=1,sticky=tk.W,padx=(0,10),pady=10)

...这是我电脑上显示的窗口样子(Windows 7,Python 2.7.3)。注意,绿色的线其实并不存在,我只是用它们来标示我认为行和列的位置。

enter image description here

到目前为止一切正常。现在我想把entNamewidth设置为60,这样可以给客户姓名输入留出更多的空间。因为我把它的columnspan设置为2,而且每个控件的sticky选项都设置为tk.W,我本以为增加entName的宽度只会让这个输入框变宽,同时窗口也会相应变宽。其他控件之间的位置应该保持不变,对吧?

结果并不是这样。把entName变宽后,entID也被推得离lblID远了:

enter image description here

那么我漏掉了什么呢?为什么entID没有保持原来的位置?有没有什么办法可以让它固定在原地,而不是把第二行单独放到一个框里?

1 个回答

8

当你把输入框做得更大时,Tkinter需要为第0列或第1列分配额外的空间。它是根据每一列的“权重”来决定的。

因为你没有明确设置权重,所以所有列的默认权重都是零。不过在你的情况下,总得有一列要变大。Tkinter会选择第一列来扩展,如果没有列设置权重的话。这就解释了为什么entID被挤到一边——第一列变宽了,以便容纳这个输入框。

如果你给第1列设置一个权重为1,那么任何额外的空间都会分配给这一列,而第0列则只会宽到刚好能放下限制它的内容(比如不跨列的任何小部件)。你可以通过grid_columnconfigure命令来实现这一点。

举个例子:

winAddNew.grid_columnconfigure(1, weight=1)

注意,权重可以是任何正整数;它代表一个比例。所以,比如说,如果你把第0列的权重设置为1,第1列的权重设置为2,那么第1列将获得第0列两倍的额外空间。

Tkinter在这方面的文档写得不太好。最权威的文档在Tcl/Tk的手册页里。具体来说,可以查看Grid算法的部分。

撰写回答