pythonpython-3.xtkintertkinter-layout

Python 3.8 tkinter stacked LabelFrame are not the same width


I am trying to build an MVC app; but am unable to get the individual stacked LabelFrame to be the same width.

The Middle Label/Entry is the same width as the Bottom Label/Combobox; however, the Top Label/Entry is not - it is in a separate class.

The sticky='ew' towards the end of my sample code aligns the TopFrame to the right or left; but I cannot get the TopFrame to be justified/same width as the BottomFrame.

What am I missing?

This is my working code using python 3.8.2

# generic python libraries
import tkinter as tk
from tkinter import ttk


class TopFrame(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)

        frame1 = ttk.LabelFrame(self, text="Top Frame")
        frame1.grid(row=0, column=0, sticky='ew', padx=5, pady=5)

        label1 = ttk.Label(frame1, text="Top Label")
        label1.grid(row=0, column=0, sticky='w', padx=5, pady=5)
        entry1 = ttk.Entry(frame1, width=5)
        entry1.grid(row=0, column=1, sticky='e', padx=5, pady=5)


class BottomFrame(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)
        frame2 = ttk.LabelFrame(self, relief='groove', text="Bottom Frame")
        frame2.grid(row=0, column=0, padx=5, pady=5)

        label2 = ttk.Label(frame2, text="Middle Label")
        label2.grid(row=0, column=0, sticky='w', padx=5, pady=5)
        entry2 = ttk.Entry(frame2, width=5)
        entry2.grid(row=0, column=1, sticky='e', padx=5, pady=5)

        label3 = ttk.Label(frame2, text="Bottom Label")
        label3.grid(row=1, column=0, sticky='w', padx=5, pady=5)
        combobox3 = ttk.Combobox(frame2)
        combobox3.grid(row=1, column=1, padx=5, pady=5)


class MyWindow(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)
        root.title('My Window')

        # these 3 lines are debug code to show the outline of the frames
        style = ttk.Style()
        style.theme_use('clam')
        style.configure("TLabelframe", bordercolor="red")

        top_frame = TopFrame(self)
        bottom_frame = BottomFrame(self)

        # sticky='e' & sticky='w' aligns the frame to the right and left respectively
        # sticky='ew' just works the same as sticky='w'
        # add line top_frame.grid_columnconfigure(0, weight=1) to fix
        top_frame.grid(row=0, column=0, sticky='ew', padx=5, pady=5)
        # the following line solves the original problem
        top_frame.grid_columnconfigure(0, weight=1)
        bottom_frame.grid(row=1, column=0, sticky='ew', padx=5, pady=5)


if __name__ == "__main__":
    root = tk.Tk()
    MyWindow(root).grid()
    root.mainloop()

Solution

  • Thanks to jasonharper for putting me on the path to a solution. Adding top_frame.grid_columnconfigure(0, weight=1) did the trick.

    I have incorporated the changes in the code above.