Tkinter / Python 网格布局与列表框
我在用Tkinter和Python做一个网格布局的时候遇到了一些麻烦。我想把菜单栏放在最上面,然后在两侧各放一个列表框,中间放几个按钮。
目前,这两个列表框都出现在窗口的右下角,而按钮却在左上角,结果还重叠了菜单按钮。
我该如何处理列表框的网格布局,考虑到它们的大小。它们能占用多个网格单元格吗?比如说,如果我把一个列表框放在(row=1, column=1),另一个放在(row=1, column=2),那么Tkinter会自动把单元格宽度调整到和列表框一样宽,还是会让它们重叠在一起呢?
def __init__(self,root):
self.frame = Frame(root, width=500)
self.frame.pack()
self.BuildMainWindow(self.frame)
self.ListboxSet = 0
self.frame.grid()
return
#displays the menu bar and options
def BuildMainWindow(self, frame):
menubar = Frame(frame,relief=RAISED,borderwidth=1)
menubar.pack()
mb_file = Menubutton(menubar,text='file')
mb_file.menu = Menu(mb_file)
mb_file.menu.add_command(label='open', command = self.openfile)
mb_file.grid(row = 1, column = 1)
mb_edit = Menubutton(menubar,text='edit')
mb_edit.menu = Menu(mb_edit)
mb_edit.grid(row=1, column = 3)
mb_file['menu'] = mb_file.menu
mb_edit['menu'] = mb_edit.menu
#upon selecting a directory from the menu and listboxes/buttons are created
def BuildListbox(self, directory):
self.listbox1 = Tkinter.Listbox()
self.listbox2 = Tkinter.Listbox()
self.listbox1.grid(row=2, column=1)
self.listbox2.grid(row=2 ,column=10)
self.listbox2.bind('<<ListboxSelect>>', lambda e:SortActions.GetWindowIndex(self,e))
self.listbox2.bind('<B1-Motion>', lambda e:SortActions.MoveWindowItem(self,e))
i = 0
for filename in sorted(os.listdir(directory)):
self.listbox1.insert(i, filename)
i = i + 1
self.bAddToListTwo = Button(self.frame, text = "->", command = lambda:SortActions.AddToListTwo(self,self.listbox1.curselection()))
self.bAddToListTwo.grid(row=5, column = 5)
self.bAddAll = Button(self.frame, text = "Add All To Playlist", command = lambda:SortActions.AddAllFiles(self))
self.bAddAll.grid(row=6, column = 5)
self.bRemoveFromListTwo = Button(self.frame, text = "Remove From Playlist", command = lambda:SortActions.RemoveFromListTwo(self,self.listbox2.curselection()))
self.bRemoveFromListTwo.grid(row=7, column = 5)
self.bSavePlaylist = Button(self.frame, text = "Save Playlist", command = lambda:SortActions.SaveList(self))
self.bSavePlaylist.grid(row=8, column = 5)
更新 - 我搞定了。果然,在初始化的时候我有一些奇怪的框架配置。
def __init__(self,root):
self.BuildMainWindow(root)
self.ListboxSet = 0
return
#displays the menu bar and options
def BuildMainWindow(self, root):
menubar = Menu(root)
root.config(menu=menubar)
# Create a menu button labeled "File" that brings up a menu
filemenu = Menu(menubar)
menubar.add_cascade(label='File', menu=filemenu)
# Create entries in the "File" menu
# simulated command functions that we want to invoke from our menus
filemenu.add_command(label='Open', command=self.openfile)
filemenu.add_separator( )
filemenu.add_command(label='Quit', command=sys.exit)
#upon selecting a directory from the menu and listboxes/buttons are created
def BuildListbox(self, directory):
self.listbox1 = Tkinter.Listbox()
self.listbox2 = Tkinter.Listbox()
self.listbox1.grid(row=1, column=1, rowspan = 4, columnspan = 5)
self.listbox2.grid(row=1 ,column=15, rowspan = 4, columnspan = 5)
self.listbox2.bind('<<ListboxSelect>>', lambda e:SortActions.GetWindowIndex(self,e))
self.listbox2.bind('<B1-Motion>', lambda e:SortActions.MoveWindowItem(self,e))
i = 0
for filename in sorted(os.listdir(directory)):
self.listbox1.insert(i, filename)
i = i + 1
self.bAddToListTwo = Button(text = "->", command = lambda:SortActions.AddToListTwo(self,self.listbox1.curselection()))
self.bAddToListTwo.grid(row=1, column = 6)
self.bAddAll = Button(text = "Add All To Playlist", command = lambda:SortActions.AddAllFiles(self))
self.bAddAll.grid(row=2, column = 6)
self.bRemoveFromListTwo = Button(text = "Remove From Playlist", command = lambda:SortActions.RemoveFromListTwo(self,self.listbox2.curselection()))
self.bRemoveFromListTwo.grid(row=3, column = 6)
self.bSavePlaylist = Button(text = "Save Playlist", command = lambda:SortActions.SaveList(self))
self.bSavePlaylist.grid(row=4, column = 6)
1 个回答
6
Tkinter中的控件可以占据多个网格单元,但你需要自己管理布局,使用columnspan
和rowspan
这两个关键词来设置.grid
。
比如,要实现这样的布局:
--------------------------------------------
| Button1 | Button2 | |
-------------------------------- Button3 |
| Label1 | Label2 | Label3 | |
--------------------------------------------
你需要做类似这样的操作:
Button1.grid(row=0,column=0,columnspan=2)
Button2.grid(row=0,column=2)
Button3.grid(row=0,column=4,rowspan=2)
Label1.grid(row=1,column=0)
Label2.grid(row=1,column=1)
Label3.grid(row=1,column=2)
非常简单的脚本
import Tkinter as tk
root = tk.Tk()
Button1 = tk.Button(root,text="Button1")
Button2 = tk.Button(root,text="Button2")
Button3 = tk.Button(root,text="Button3")
Label1 = tk.Label(root,text="Label1")
Label2 = tk.Label(root,text="Label2")
Label3 = tk.Label(root,text="Label3")
Button1.grid(row=0,column=0,columnspan=2)
Button2.grid(row=0,column=2)
Button3.grid(row=0,column=4,rowspan=2)
Label1.grid(row=1,column=0)
Label2.grid(row=1,column=1)
Label3.grid(row=1,column=2)
root.mainloop()