Tkinter网格奇怪现象

2 投票
3 回答
1099 浏览
提问于 2025-04-20 04:46

今天我做了一个简单的基于网格的 Tkinter Frame 子类。它的主控件是一个 Tk() 对象。

root = Tk()
root.title('Rep Logger UI')
root.geometry('500x500')

mother = rep_ui(master=root)
mother.mainloop()

我想做的就是把 rep_ui 窗口分成两个相同宽度的框(一个红色,一个蓝色),然后在每个框里放几个小部件。

但是我好像做错了什么。红色和蓝色的框没有完全填满窗口。要么它们没有完全填满 rep_ui 类,要么 rep_ui 类在它的主控件(root)里没有正确扩展?

另外,尽管我给它们设置了相同的 weight,但红色和蓝色的框的宽度却不一样。

def __init__(self, master=None):
    Frame.__init__(self, master)

    """to make the rep_ui frame expand into the entire OS window."""

    self.master.rowconfigure(    0, weight = 1 )              # outer-bounds' row[0] weight set
    self.master.columnconfigure( 0, weight = 1 )              # outer-bounds' col[0] weight set

    self.grid(sticky=W+E+N+S)                                 # EWNS-sticky mode set

    self.columnconfigure(        0, weight = 1 )              # column[0] weight set
    self.columnconfigure(        1, weight = 1 )              # column[1] weight set

    self.rowconfigure(           0, weight = 1 )              #    row[0] weight set
    self.rowconfigure(           1, weight = 1 )              #    row[1] weight set


    """ left and right frames"""
    self.fl = Frame(self, bg="red")                           # RED  Frame ( left )
    self.fr = Frame(self, bg="blue")                          # BLUE Frame ( right )

    self.fl.grid( row=0, column=0,  sticky=N+S+W+E)           # .grid() RED  one
    self.fr.grid  row=0, column=1,  sticky=N+S+W+E)           # .grid() BLUE one

这是我描述的问题的图片: http://imgur.com/MkSE9yt

3 个回答

-2

你可以试试使用 place 布局管理器:

self.fl.place( relx = 0.0, rely = 0.0, relwidth = 0.5, relheight = 1.0 )
self.fr.place( relx = 0.5, rely = 0.0, relwidth = 0.5, relheight = 1.0 )

使用父级控件的相对比例非常强大,而且代码简单,容易验证,未来也能适应界面缩放,不会像复杂的界面设计那样在使用过程中遇到其他问题和意外的副作用。

在这里输入图片描述

root = Tkinter.Tk()
aLF  = Tkinter.Frame(  root, bg = "red" )
aRF  = Tkinter.Frame(  root, bg = "blue")
aLF.place(                   relx = 0.0,
                                 rely = 0.0, relwidth = 0.5, relheight = 1.0 )
aRF.place(                   relx = 0.5,
                                 rely = 0.0, relwidth = 0.5, relheight = 1.0 )
aTextR = Tkinter.Label( aRF, bg = "white", text = "aFR := frame right" )
aTextR.place(                relx = 0.0,
                                 rely = 0.0 )
aTextL = Tkinter.Label( aLF, bg = "white", text = "aFL := frame left" )
aTextL.place(                relx = 0.0,
                                 rely = 0.0 )
root.title( 'Rep Logger UI')
root.geometry( '500x500' )
root.lift()

并进行交叉验证

root.geometry( '500x500' )
root.geometry( '300x100' )
root.geometry( '400x300' )
root.geometry( '600x150' )
1

weight 参数只影响如何分配 额外 空间。也就是说,网格管理器首先会处理所有的“孙子”控件,然后如果还有多余的空间,就会根据提供的权重把这些空间分配给子控件。 (这里有详细说明:权重参数“在分配额外空间时,给出这一列或行的相对权重”)

下面是一个直观的解释: 展示额外空间分配的图示

至于底部的空白部分,我觉得我们需要查看其余的代码才能弄清楚。

3

为什么这些窗口的宽度不一样?

原因很简单:红色框里有一个文本小部件。问题在于你给两个框都加了 weight 参数,但没有给里面的小部件加。对于文本,你可以使用类似这样的设置:

self.fl.rowconfigure(0, weight=1)
self.fl.columnconfigure(0, weight=1)

为什么会有这个空白区域?

这是因为你在这里配置了第1行:

self.rowconfigure(1, weight=1)

虽然这个配置没有被使用,但它还是会显示出来。你可以删除或者注释掉这一行,这样就能正常工作了。

撰写回答