在窗口变化时调整Tkinter列表框小部件大小

18 投票
2 回答
39595 浏览
提问于 2025-04-16 07:50

我刚开始学习Tkinter,想要让我的Listbox(列表框)在主窗口大小改变时自动调整大小。

简单来说,我希望这个列表框的高度和宽度能够随着窗口的变化而变化。如果有人能给我一些相关的文档或者提供一点代码和建议,我会非常感激。

2 个回答

3

让列表框在窗口大小改变时能够伸缩,主要有两种方法:使用 .pack().grid() 方法。

系统信息:

Windows 7, Python 3.8.1, tkinter 版本: 8.6

.pack()

我发现最简单的方法是使用 .pack() 方法,并且设置 fill=expand=True 选项。

import tkinter as tk

root=tk.Tk()                                              #Creates the main window

listbox=tk.Listbox(root)                                  #Create a listbox widget

listbox.pack(padx=10,pady=10,fill=tk.BOTH,expand=True)    #fill=tk.BOTH, stretch vertically and horizontally
                                                          #fill=tk.Y, stretch vertically
                                                          #fill=tk.X, stretch horizontally

如果你的列表框放在一个 框架 中,那么这个框架也需要使用 fill=expand=True 选项。

import tkinter as tk

root=tk.Tk()

frame1=tk.Frame(root)
frame1.pack(fill=tk.BOTH, expand=True)

listbox=tk.Listbox(frame1)
listbox.pack(padx=10,pady=10,fill=tk.BOTH,expand=True)

.grid()

另一种方法是使用 .grid() 方法,并利用 sticky= 选项。此外,你还需要配置列表框所在的

import tkinter as tk

root=tk.Tk()  #create window
root.columnconfigure(0,weight=1)    #confiugures column 0 to stretch with a scaler of 1.
root.rowconfigure(0,weight=1)       #confiugures row 0 to stretch with a scaler of 1.

listbox=tk.Listbox(root)
listbox.grid(row=0,column=0,padx=5,pady=5,sticky='nsew')   

sticky 选项会让列表框在被拉伸时“粘”在单元格的“北”(上)、“南”(下)、“东”(右)和“西”(左)边。

如果你的列表框放在一个 框架 中,你还需要配置这个 框架 所在的 ,以及列表框所在的

import tkinter as tk

root=tk.Tk()               #create window
root.columnconfigure(0,weight=1)  
root.rowconfigure(0,weight=1)

frame1=tk.Frame(root)
frame1.grid(row=0,column=0,sticky='nsew')
frame1.columnconfigure(0,weight=1)
frame1.rowconfigure(0,weight=1)

listbox=tk.Listbox(frame1)
listbox.grid(row=0,column=0,padx=5,pady=5,sticky='nsew')

.pack() 和 .grid()

还有一种方法,但有些人不太喜欢。这第三种方法是同时使用 .pack().grid() 方法在同一个脚本中。只要每个容器中只使用一种管理方式,你就可以在同一个脚本中混合使用不同的布局管理方法。下面有个例子。

import tkinter as tk

root=tk.Tk()               #create window

frame1=tk.Frame(root)                                #container: root
frame1.pack(fill=tk.BOTH,expand=True)                               
frame1.columnconfigure(0,weight=1)
frame1.rowconfigure(0,weight=1)
frame1.rowconfigure(1,weight=1)

listbox=tk.Listbox(frame1)                            #container: frame1
listbox.grid(row=0,rowspan=2,column=0,padx=5,pady=5,sticky='nsew') 

btn1=tk.Button(frame1,text='Demo1')                   #container: frame1        
btn1.grid(row=0,column=1, padx=5, pady=5)                          

btn2=tk.Button(frame1,text='Demo2')                   #container: frame1     
btn2.grid(row=1,column=1, padx=5, pady=5)                          

frame2=tk.Frame(root)                                 #container: root 
frame2.pack()

btn3=tk.Button(frame2,text='Demo3')                   #container: frame2
btn3.grid(row=0,column=0)                                          

你可以看到上面的框架使用了 .pack(),而列表框和按钮使用了 .grid()。这是因为这些框架是在 容器中,而列表框和按钮则是在各自的框架中。


要检查你的 tkinter 版本,可以使用:

import tkinter as tk
print(tk.TkVersion)

如果你想了解 fillexpand 之间的区别,请查看以下链接。 https://effbot.org/tkinterbook/pack.htm

14

你想了解一下几种布局管理器,分别是packgrid。它们可以帮助你在窗口中放置小部件,并且可以设置这些小部件是否可以随窗口大小变化而变化。还有一种布局管理器叫place,不过这个用得比较少。

这里有个简单的例子:

import tkinter as tk

root = tk.Tk()
scrollbar = tk.Scrollbar(root, orient="vertical")
lb = tk.Listbox(root, width=50, height=20, yscrollcommand=scrollbar.set)
scrollbar.config(command=lb.yview)

scrollbar.pack(side="right", fill="y")
lb.pack(side="left",fill="both", expand=True)

for i in range(0,100):
    lb.insert("end", "item #%s" % i)

root.mainloop()

如果你想用grid代替pack,只需要把调用pack的那两行删掉,然后用这四行代码替换:

root.grid_rowconfigure(0, weight=1)
root.grid_columnconfigure(0, weight=1)

scrollbar.grid(row=0, column=1, sticky="ns")
lb.grid(row=0, column=0, sticky="nsew")

需要注意的是,使用grid时,你还需要额外设置一下包含列表框的行和列的weight,否则tkinter不会给这个小部件分配额外的空间。

撰写回答