I have a device that understands multiple serial protocols. During development I created simple Tkinter UIs to play with the protocols. Each protocol got a new UI. Since the protocols have lots of commands, I implemented the entire UI within a scrollable canvas to permit it to be scrolled when used on smaller displays. The separate UIs worked fine, and I'm now trying to combine the separate UIs into a tabbed UI.
The common elements of each UI are the serial port selector, which I separated out and put into a separate top frame. I then implemented a notebook, and put each protocol UI into a frame for each tab.
But I'm unable to properly control sizing: I want the root window width to be fixed at the maximum width of any of the protocol frames or serial selector frame, 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 notebook is resized/scrolled).
Below is what I have so far. All the pieces are present, but the notebook doesn't fill the complete window width, and the notebook doesn't resize when the window is resized (resizing just adds blank 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's 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's 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 do I lock down the top serial frame, expand the notebook to full width, and force window resizing to only affect the notebook frame? I'm a Tkinter newbie, so please be gentle if I've missed something "obvious".
TIA!