I'm working on a Tkinter GUI. I want to make two separate frames have the same width so that they line up vertically. I do not know of any way to put them inside the same structure because they need to be independently scrollable in the vertical direction (that functionality is not yet in the code).
I tried various ways of what I thought was setting the lower frame width equal to the upper frame width because the lower frame has a smaller width by default, but that seems to have no effect. See lines
# Match widths
self.vert_frames[-1][1].configure(width=self.vert_frames[-1][0].cget("width"))
I'm new to both stackoverflow and python, so let me know if you need more details or have corrections to my question formatting or anything else. I've been a longtime reader, so I'm excited to hear what solutions you all know about!
Thank you all in advance.
# Imports
import tkinter as tk
from tkinter import ttk
# Define GUI CLASS
class tl_GUI:
# initialize the GUI
def __init__(self, root):
self.root = root
# set geometry
# self.root.geometry("480x320+150+150") # remove if not used in final version
self.root.grid_rowconfigure(0, weight=1)
self.root.grid_columnconfigure(0, weight=1)
# SET STRUCTURE
# create data_canvas
self.data_canvas = tk.Canvas(self.root)
self.data_canvas.grid(row = 0, column = 0, sticky = "nsew")
# create 2-pane PanedWindow
self.data_panedwindow = ttk.Panedwindow(self.data_canvas, orient="vertical")
self.data_panedwindow.pack(fill="both", expand=True)
# create input canvas
self.in_canvas = tk.Canvas(self.data_panedwindow)
self.data_panedwindow.add(self.in_canvas, weight=1)
# create input frame
self.in_frame = ttk.Frame(self.in_canvas, relief="sunken")
self.in_frame.pack()
# create output canvas
self.out_canvas = tk.Canvas(self.data_panedwindow)
self.data_panedwindow.add(self.out_canvas, weight=1)
# create output frame
self.out_frame = ttk.Frame(self.out_canvas, relief="sunken")
self.out_frame.pack()
# CREATE INITIAL I/O FRAMES
self.curr_compares = 0
self.vert_frames = []
for init_frames in range(0, 2):
self.add_compareIO()
# define method to add a vertical I/O frame
def add_compareIO(self):
# create input and output frames
self.vert_frames.append([])
self.vert_frames[-1].append(ttk.Frame(self.in_frame, padding = 2, relief = "groove"))
self.vert_frames[-1].append(ttk.Frame(self.out_frame, padding = 2, relief = "groove"))
self.vert_frames[-1][0].grid(row = 0, column = self.curr_compares)
self.vert_frames[-1][1].grid(row = 0, column = self.curr_compares)
# close_frame
col = len(self.vert_frames)-1 # may be able to use self.curr_compares instead
self.vert_frames[-1][0].button_close = ttk.Label(self.vert_frames[-1][0],
text="[Image here]")
self.vert_frames[-1][0].button_close.grid(row = 0, column = 0, columnspan=2, stick = "e")
self.vert_frames[-1][0].button_close.bind("<Button-1>",
lambda e: self.destroy_frame(col_num=col))
self.vert_frames[-1][1].button_close = ttk.Label(self.vert_frames[-1][1],
text="[Image here]")
self.vert_frames[-1][1].button_close.grid(row = 0, column = 0, columnspan=2, stick = "e")
self.vert_frames[-1][1].button_close.bind("<Button-1>",
lambda e: self.destroy_frame(col_num=col))
# populate inputs
self.vert_frames[-1][0].label_hpp = ttk.Label(self.vert_frames[-1][0], text = "INPUT1")
self.vert_frames[-1][0].entry_hpp = ttk.Entry(self.vert_frames[-1][0], width = 13)
self.vert_frames[-1][0].entry_hpp.bind("<KeyRelease>", lambda e: self.refresh_calculations(col)) # recalculate when any keyboard button is pressed
self.vert_frames[-1][0].label_int_rate = ttk.Label(self.vert_frames[-1][0], text = "INPUT2")
self.vert_frames[-1][0].entry_int_rate = ttk.Entry(self.vert_frames[-1][0], width = 13)
self.vert_frames[-1][0].entry_int_rate.bind("<KeyRelease>", lambda e: self.refresh_calculations(col))
self.vert_frames[-1][0].label_RENAME = ttk.Label(self.vert_frames[-1][0], text = "INPUT3")
self.vert_frames[-1][0].entry_RENAME = ttk.Entry(self.vert_frames[-1][0], width = 13)
self.vert_frames[-1][0].entry_RENAME.bind("<KeyRelease>", lambda e: self.refresh_calculations(col))
self.vert_frames[-1][0].label_hpp.grid(row = 1, column = 0)
self.vert_frames[-1][0].entry_hpp.grid(row = 1, column = 1)
self.vert_frames[-1][0].label_int_rate.grid(row = 2, column = 0)
self.vert_frames[-1][0].entry_int_rate.grid(row = 2, column = 1)
self.vert_frames[-1][0].label_RENAME.grid(row = 3, column = 0)
self.vert_frames[-1][0].entry_RENAME.grid(row = 3, column = 1)
# populate outputs
self.vert_frames[-1][1].label_tcl = ttk.Label(self.vert_frames[-1][1], text = "OUTPUT1: {}".format(10))
self.vert_frames[-1][1].label_tcl.grid(row = 1, column = 0)
# Match widths
self.vert_frames[-1][1].configure(width=self.vert_frames[-1][0].cget("width"))
# update counter
self.curr_compares += 1
def destroy_frame(self, col_num):
self.vert_frames[col_num][0].grid_forget()
self.vert_frames[col_num][1].grid_forget()
self.vert_frames[col_num][0].destroy()
self.vert_frames[col_num][1].destroy()
self.vert_frames[col_num] = []
# define method to refresh calculations (wrapper for actual calcs)
def refresh_calculations(self, col):
pass
# Execute code
if __name__ == "__main__":
root = tk.Tk()
my_gui = tl_GUI(root)
root.mainloop()