Use tkinter grid instead of pack. Python code: def setup_ui(self):
"""Set up the user interface."""
self.create_sidebar()
self.create_main_frame()
self.create_header_frame()
self.create_table_frame()

def create_sidebar(self):
"""Create the sidebar with functional and spacer frames."""
functional_sidebar = self._create_frame(
parent=self.root,
width=self.sidebar_width,
bg=self.sidebar_color,
side='left',
anchor='nw',
fill='y'
)
spacer_frame = self._create_frame(
parent=self.root,
width=self.static_frame_width,
bg=self.background_color,
side='left',
anchor='nw',
fill='y'
)

functional_sidebar.pack_propagate(False)
self._add_normal_buttons(functional_sidebar)
self._add_scrollable_canvas(functional_sidebar)
self._add_delete_table_section(functional_sidebar)

def _create_frame(
self,
parent: tk.Widget,
width: Optional[int],
bg: str,
side: str,
anchor: str,
fill: str,
expand: bool = False
) -> tk.Frame:
"""Create and pack a frame."""
frame = tk.Frame(parent, width=width, bg=bg, bd=0, relief='flat')
frame.pack(side=side, anchor=anchor, fill=fill, expand=expand)
return frame

def _add_normal_buttons(self, sidebar: tk.Frame):
"""Add buttons to the sidebar."""
normal_buttons_frame = self._create_frame(
parent=sidebar,
width=None,
bg=self.sidebar_color,
side='top',
anchor='nw',
fill='x'
)
create_table_label = self._create_clickable_label(
parent=normal_buttons_frame,
text="Create New Table",
command=self.create_new_table,
anchor='center'
)
create_table_label.pack(pady=10, anchor='center')
self.add_custom_hover(create_table_label)
self._add_separator(normal_buttons_frame)

def _add_scrollable_canvas(self, sidebar: tk.Frame):
"""Add scrollable canvas for table labels."""
scrollbar_frame = self._create_frame(
parent=sidebar,
width=None,
bg=self.sidebar_color,
side='top',
anchor='nw',
fill='both',
expand=True
)

canvas = tk.Canvas(
    scrollbar_frame,
    bg=self.sidebar_color,
    highlightthickness=0,
    width=self.sidebar_width - 15
)
canvas.pack(side="left", fill="both", expand=True)

self.config_scrollbar_style()

scrollbar = ttk.Scrollbar(
    scrollbar_frame,
    orient="vertical",
    command=canvas.yview,
    style="Custom.Vertical.TScrollbar"
)
scrollbar.pack(side="right", fill="y")
canvas.configure(yscrollcommand=scrollbar.set)

self.table_labels_frame = tk.Frame(canvas, bg=self.sidebar_color)
canvas.create_window((0, 0), window=self.table_labels_frame, anchor="nw")

canvas.bind_all("<MouseWheel>", lambda event: canvas.yview_scroll(int(-1 * (event.delta / 120)), "units"))

self._bind_scrollbar_events(canvas, scrollbar, scrollbar_frame)

def _bind_scrollbar_events(self, canvas: tk.Canvas, scrollbar: ttk.Scrollbar, scrollbar_frame: tk.Frame):
"""Manage scrollbar visibility based on content size."""
def configure_scrollbar(event: Optional[tk.Event] = None):
canvas.update_idletasks()
canvas_height = scrollbar_frame.winfo_height()
content_height = self.table_labels_frame.winfo_reqheight()

    if content_height > canvas_height:
        scrollbar.pack(side="right", fill="y")
        canvas.bind_all("<MouseWheel>", lambda event: canvas.yview_scroll(int(-1 * (event.delta / 120)), "units"))
    else:
        scrollbar.pack_forget()
        canvas.unbind_all("<MouseWheel>")

    canvas.configure(scrollregion=canvas.bbox("all"))

self.table_labels_frame.bind("<Configure>", configure_scrollbar)
scrollbar_frame.bind("<Configure>", configure_scrollbar)

def _add_delete_table_section(self, sidebar: tk.Frame):
"""Add delete table option to the sidebar."""
self._add_separator(sidebar)
delete_table_label = self._create_clickable_label(
parent=sidebar,
text="🗑 Delete Selected Table",
command=self.delete_table,
anchor='center'
)
delete_table_label.pack(side='bottom', anchor='center', pady=10)
self.add_custom_hover(delete_table_label)

def _add_separator(self, parent: tk.Widget):
"""Add a horizontal separator."""
ttk.Separator(parent, orient='horizontal').pack(fill='x')

def _create_clickable_label(
self,
parent: tk.Widget,
text: str,
command,
allow_rename: bool = False,
anchor: str = 'w'
) -> tk.Label:
"""Create a clickable label with optional rename functionality."""
cursor = "arrow" if allow_rename else "hand2"
label = tk.Label(
parent,
text=text,
bg=self.button_color,
fg=self.text_color,
cursor=cursor,
anchor=anchor
)
label.bind("", lambda _: command())
if allow_rename:
label.bind("", lambda _: self.begin_rename(text))
return label

def create_main_frame(self):
"""Create the main frame."""
self.main_frame = tk.Frame(self.root)
self.main_frame.pack(expand=True, fill='both', side='right')

def create_header_frame(self):
"""Create the header with filter and settings options."""
header_frame = self._create_frame(
parent=self.main_frame,
width=None,
bg=self.background_color,
side='top',
anchor='nw',
fill='x'
)
header_frame.config(height=self.header_height)
header_frame.pack_propagate(False)

tk.Label(
    header_frame,
    text="Filter:",
    bg=self.background_color,
    fg=self.text_color
).pack(side='left')

self.filter_entry = tk.Entry(
    header_frame,
    fg=self.text_color
)
self.filter_entry.pack(side='left', padx=(0, 10))
self.filter_entry.bind("<KeyRelease>", lambda _: self.apply_filter())

settings_label = tk.Label(
    header_frame,
    text="...",
    bg=self.background_color,
    fg=self.text_color,
    cursor="hand2",
    anchor='e'
)
settings_label.place(relx=1.0, rely=0.0, anchor='ne', x=-40, y=20)

settings_menu = tk.Menu(settings_label, tearoff=0)
settings_menu.add_command(label="Export Table", command=self.export_table)
settings_menu.add_command(label="Import Table", command=self.import_file)
settings_menu.add_command(label="Rename Headers", command=self.rename_headers)

settings_label.bind("<Button-1>", lambda e: settings_menu.post(e.x_root, e.y_root))
settings_label.bind("<Enter>", lambda _: settings_label.config(bg=self.button_color_selected))
settings_label.bind("<Leave>", lambda _: settings_label.config(bg=self.background_color))

def create_table_frame(self):
"""Create the table frame."""
self.table_frame = tk.Frame(
self.main_frame,
bg=self.background_color
)
self.table_frame.pack(expand=True, fill='both')