title: How can I make two Tkinter ttk.Frame widgets the same width?
body: <p>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).</p>
  <p>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</p>
  <pre><code>        # Match widths
          self.vert_frames[-1][1].configure(width=self.vert_frames[-1][0].cget(&quot;width&quot;))
  </code></pre>
  <p>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!</p>
  <p>Thank you all in advance.</p>
  <pre><code># 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(&quot;480x320+150+150&quot;) # 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 = &quot;nsew&quot;)
          
          # create 2-pane PanedWindow
          self.data_panedwindow = ttk.Panedwindow(self.data_canvas, orient=&quot;vertical&quot;)
          self.data_panedwindow.pack(fill=&quot;both&quot;, 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=&quot;sunken&quot;)
          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=&quot;sunken&quot;)
          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 = &quot;groove&quot;))
          self.vert_frames[-1].append(ttk.Frame(self.out_frame, padding = 2, relief = &quot;groove&quot;))
          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=&quot;[Image here]&quot;)
          self.vert_frames[-1][0].button_close.grid(row = 0, column = 0, columnspan=2, stick = &quot;e&quot;)
          self.vert_frames[-1][0].button_close.bind(&quot;&lt;Button-1&gt;&quot;, 
                                            lambda e: self.destroy_frame(col_num=col))
          self.vert_frames[-1][1].button_close = ttk.Label(self.vert_frames[-1][1], 
                                                            text=&quot;[Image here]&quot;)
          self.vert_frames[-1][1].button_close.grid(row = 0, column = 0, columnspan=2, stick = &quot;e&quot;)
          self.vert_frames[-1][1].button_close.bind(&quot;&lt;Button-1&gt;&quot;, 
                                            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 = &quot;INPUT1&quot;)
          self.vert_frames[-1][0].entry_hpp = ttk.Entry(self.vert_frames[-1][0], width = 13)
          self.vert_frames[-1][0].entry_hpp.bind(&quot;&lt;KeyRelease&gt;&quot;, 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 = &quot;INPUT2&quot;)
          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(&quot;&lt;KeyRelease&gt;&quot;, lambda e: self.refresh_calculations(col))
          
          self.vert_frames[-1][0].label_RENAME = ttk.Label(self.vert_frames[-1][0], text = &quot;INPUT3&quot;)
          self.vert_frames[-1][0].entry_RENAME = ttk.Entry(self.vert_frames[-1][0], width = 13)
          self.vert_frames[-1][0].entry_RENAME.bind(&quot;&lt;KeyRelease&gt;&quot;, 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 = &quot;OUTPUT1: {}&quot;.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(&quot;width&quot;))
          
          # 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__ == &quot;__main__&quot;:
      root = tk.Tk()
      my_gui = tl_GUI(root)
      root.mainloop()
  </code></pre>