Tkinter multi-frame resizing

I have a device that understands several serial protocols. During development, I created simple Tkinter user interfaces for working with protocols. Each protocol received a new interface. Since protocols have many commands, I implemented the entire user interface in a scrollable canvas to allow it to scroll when used on smaller displays. The individual interfaces worked fine, and now I'm trying to combine the individual user interfaces into a tabbed user interface.

The common elements of each user interface are the serial port selector, which I selected and placed in a separate top frame. Then I implemented a laptop and put each protocol user interface in a frame for each tab.

But I can't control the size correctly: I want the width of the root window to be fixed with the maximum width of any of the protocol frames or selector selector selectors with horizontal resizing disabled. I want the serial selector to always be present and not be affected when the window is vertically resized (only the size or scroll size of the laptop).

Below I am still. All parts are present, but the laptop does not fill the full width of the window, and the laptop does not resize when the window is resized (resizing just adds a space).

def main(): ## Main window root = Tkinter.Tk() root.title("Multi-Protocol UI") ## Grid sizing behavior in window root.grid_rowconfigure(0, weight=0) root.grid_rowconfigure(1, weight=1) root.grid_columnconfigure(0, weight=1) root.grid_columnconfigure(1, weight=0) ## Window content upper = ttk.Frame(root) # Serial port selector upper.grid(row=0) upper.grid_rowconfigure(0, weight=0) upper.grid_columnconfigure(0, weight=1) upper.grid_columnconfigure(1, weight=0) lower = ttk.Frame(root) # For protocols lower.grid(row=1) lower.grid(row=1, sticky='nswe') lower.grid_rowconfigure(0, weight=1) lower.grid_columnconfigure(0, weight=1) lower.grid_columnconfigure(1, weight=0) # Setup serial control frame serial = SerialFrame(master=upper) # Serial port selector widget + Open button ## Protocol GUIs are large: Use a form within a scrollable canvas. cnv = Tkinter.Canvas(lower) cnv.grid(row=0, column=0, sticky='nswe') cnv.grid_rowconfigure(0, weight=1) cnv.grid_columnconfigure(0, weight=1) cnv.grid_columnconfigure(1, weight=0) # Scrollbar for canvas vScroll = Tkinter.Scrollbar( lower, orient=Tkinter.VERTICAL, command=cnv.yview) vScroll.grid(row=0, column=1, sticky='ns') cnv.configure(yscrollcommand=vScroll.set) # Frame in canvas window = Tkinter.Frame(cnv) window.grid() # Put the frame in the canvas scrollable zone cnv.create_window(0, 0, window=window, anchor='nw') # Setup the notebook (tabs) within the scrollable window notebook = ttk.Notebook(window) frame1 = ttk.Frame(notebook) frame2 = ttk.Frame(notebook) notebook.add(frame1, text="ProtoA") notebook.add(frame2, text="ProtoB") notebook.grid(row=0, column=0, sticky='nswe') # Create tab frames protoA = ProtoAFrame(master=frame1) protoA.grid() protoA.update_idletasks() protoB = ProtoBFrame(master=frame2) protoB.grid() protoB.update_idletasks() ## Update display to get correct dimensions root.update_idletasks() window.update_idletasks() ## Configure size of canvas scrollable zone cnv.configure(scrollregion=(0, 0, window.winfo_width(), window.winfo_height())) # Not resizable in width: root.resizable(width=0, height=1) ## Go! root.mainloop() 

How to lock the top sequential frame, expand the laptop to full width and resize the window to affect only the frame of the laptop? I am new to Tkinter, so please be careful if I miss something โ€œobviousโ€.

TIA!

+4
source share
1 answer

You have widgets nested inside widgets. Even if you have a laptop that needs to expand correctly in the container, you also need to make sure that each container upwards also expands correctly. You have not done so. For example, ask yourself if the canvas was set up for proper growth inside lower .

As you get started, here's what I recommend. Instead of trying to get everything at once, choose the divide and conquer approach. First, create a framework for the main areas of your GUI. Do nothing but these frames, and get them resized to be exactly what you want. This helps at this stage to give everyone their own color so that you can clearly see where the widgets are. You can always change the color later. Also, if you have only two widgets or all of your widgets are oriented horizontally or vertically, a package is often easier to use than a grid.

For instance:

 upper.pack(side="top", fill="x", expand=False) lower.pack(side="bottom", fill="both", expand=True) 

After you have these main parts, the size of which will be resized accordingly, you need to solve the problem for only one of these areas. Select an area and do the same: add to your child widgets or split into frames if you have areas inside the area. After you do this, rinse, rinse, repeat.

+6
source

Source: https://habr.com/ru/post/1447019/


All Articles