I have a tkinter app which will be used in multiple screen sizes. I want to place a listbox in the left side and place some buttons underneath it. I also have a label to place on top of the listbox. I am using grid
management to place all the widgets so its consistent with different screen sizes. So far I could place all of them left aligned to the screen, but I would like to move the listbox a little bit up, so that there will be no space from the top. How can I manage that?
Here's a MWE
import tkinter as tk
from tkinter import ttk
from tkmacosx import Button
class Window(tk.Tk):
def __init__(self,*args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
tk.Tk.wm_title(self, "OCTOLE")
container = tk.Frame(self)
container.pack(side="top", fill="both", expand = True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
self.frames = {}
for F in (StartPage, PageOne, PageTwo):
frame = F(container, self)
self.frames[F] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame(StartPage)
self.attributes("-topmost", False)
self.wm_state('zoomed')
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
class StartPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self,parent,bg='#192232')
toolbar0 = tk.Frame(self,bg="#393951")
toolbar0.grid_rowconfigure(0, weight=1)
toolbar0.grid_columnconfigure(0, weight=1)
toolbar0.pack(side=tk.TOP, fill=tk.X)
label = ttk.Label(toolbar0, text="OLE Analyser")
label.place(relx=0.5, rely=0.5, anchor="center")
exit_btn = Button(toolbar0, text="EXIT",command=lambda: app.destroy())
exit_btn.pack(side="right", padx=5, pady=5)
button2 = Button(toolbar0, text="Comparison",command=lambda: controller.show_frame(PageTwo))
button2.pack(side="right", padx=5, pady=5)
button1 = Button(toolbar0, text="Analysis",command=lambda: controller.show_frame(PageOne))
button1.pack(side="right", padx=5, pady=5)
class PageOne(tk.Frame):
def __init__(self,parent, controller):
tk.Frame.__init__(self, parent,bg='#192232')
toolbar1 = tk.Frame(self,bg="#393951")
toolbar1.pack(side=tk.TOP, fill=tk.X)
label = ttk.Label(toolbar1, text="Analysis")
label.place(relx=0.5, rely=0.5, anchor="center")
exit_btn = Button(toolbar1, text="EXIT",command=lambda: app.destroy())
exit_btn.pack(side="right", padx=5, pady=5)
button2 = Button(toolbar1, text="Comparison",command=lambda: controller.show_frame(PageTwo))
button2.pack(side="right", padx=5, pady=5)
button1 = Button(toolbar1, text="Home",command=lambda: controller.show_frame(StartPage))
button1.pack(side="right", padx=5, pady=5)
frame = tk.Frame(self, bg='#192232')
frame.pack(side="left", padx=15, pady=5)
files_label = tk.Label(frame,text="Spectrum Files",bg='#192232', fg= '#C4BDED',font=16)
files_label.grid(row=0, column=0, sticky="w")
scrollbarx = ttk.Scrollbar(frame, orient=tk.HORIZONTAL)
scrollbarx.grid(row=2, column=0, sticky="ew")
listb = tk.Listbox(frame, selectmode = "multiple",height=40,width=40,bd=3,xscrollcommand=scrollbarx.set)
listb.grid(row=1, column=0, sticky="n")
browse_btn = Button(frame,text="Browse",borderless=True,command=lambda: ask())
browse_btn.grid(row=3, column=0, sticky="w")
clb_btn = Button(frame,text="Clear Files",borderless=True,command=lambda:clear_listbox())
clb_btn.grid(row=3, column=0, sticky="e")
submit_btn = Button(frame,text="Submit Selection",command=lambda:sumit())
submit_btn.grid(row=4, column=0, sticky="w")
def ask():
pass
scrollbarx.config(command=listb.xview)
def sumit():
pass
def clear_listbox():
listb.delete(0,tk.END)
class PageTwo(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent,bg='#192232')
toolbar2 = tk.Frame(self,bg="#393951")
toolbar2.pack(side=tk.TOP, fill=tk.X)
if __name__ == "__main__":
app = Window()
app.update()
app.mainloop()
The problem isn't with your use of grid
. The problem is with your use of pack
.
You've packed the frame that the listbox is on to the left side, but you haven't requested that the frame fill the space it was allocated. Something like the following will cause the frame to fill the left side top-to-bottom, causing the listbox to appear at the top:
frame.pack(side="left", padx=15, pady=5, fill="y")