Tkinter Frame Size

I got stuck for several days trying to figure out how I can dynamically resize the frame in TKInter using this approach.

class SampleApp(tk.Tk): def __init__(self, *args, **kwargs): tk.Tk.__init__(self, *args, **kwargs) # the container is where we'll stack a bunch of frames # on top of each other, then the one we want visible # will be raised above the others 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): page_name = F.__name__ frame = F(container, self) self.frames[page_name] = frame # put all of the pages in the same location; # the one on the top of the stacking order # will be the one that is visible. frame.grid(row=0, column=0, sticky="nsew") self.show_frame("StartPage") def show_frame(self, page_name): '''Show a frame for the given page name''' frame = self.frames[page_name] frame.tkraise() class StartPage(tk.Frame): def __init__(self, parent, controller): tk.Frame.__init__(self, parent) self.controller = controller label = tk.Label(self, text="This is the start page", font=TITLE_FONT) label.pack(side="top", fill="x", pady=10) button1 = tk.Button(self, text="Go to Page One", command=lambda: controller.show_frame("PageOne")) button2 = tk.Button(self, text="Go to Page Two", command=lambda: controller.show_frame("PageTwo")) button1.pack() button2.pack() class PageOne(tk.Frame): def __init__(self, parent, controller): tk.Frame.__init__(self, parent) self.controller = controller label = tk.Label(self, text="This is page 1", font=TITLE_FONT) label.pack(side="top", fill="x", pady=10) button = tk.Button(self, text="Go to the start page", command=lambda: controller.show_frame("StartPage")) button.pack() class PageTwo(tk.Frame): def __init__(self, parent, controller): tk.Frame.__init__(self, parent) self.controller = controller label = tk.Label(self, text="This is page 2", font=TITLE_FONT) label.pack(side="top", fill="x", pady=10) button = tk.Button(self, text="Go to the start page", command=lambda: controller.show_frame("StartPage")) button.pack() if __name__ == "__main__": app = SampleApp() app.mainloop() 

I copied this code from Switching between two frames in tkinter because I am following the same approach.

The problem I am facing is that when using this approach, all frames fit into a container, and the size of this container is the size of its largest frame. The transition from one frame to another does not change the size of the window in dynamic mode and leads to huge free space in small frames. I tried different methods to make all the frames in the container dynamically mutable, but without much success. Can anyone suggest what I can do?

+2
python user-interface tkinter
Mar 14 '16 at 15:06
source share
1 answer

Instead of stacking frames, make sure that only one of them is controlled by the grid at a time. You can do this by calling grid_remove() current frame, and then grid() in the new frame. Or, being lazy, you can call grid_remove() everyone so you don't have to remember which page is current.

 def show_frame(self, page_name): '''Show a frame for the given page name''' for frame in self.frames.values(): frame.grid_remove() frame = self.frames[page_name] frame.grid() 

Note. Automatic resizing stops working if you specify a fixed size for the main window using the geometry method in the root window or the user manually resizes the window. This is because tkinter assumes that if something explicitly asks for the size of the window, that size must be respected.

If you always want to resize the window, you must reset the geometry to the empty line. You can add this as the last statement in the show_frame method:

 frame.winfo_toplevel().geometry("") 
+1
Mar 14 '16 at 15:22
source share



All Articles