0
votes

Is there a simple way to get nested frames to look like one frame - preferably using the grid layout manager? This is relatively easy to do when the frames are not nested (i.e. the frames are children of the same parent widget - see second image).
The problem is the (1 pixel?) separation that appears between the frames. Eliminate that and my problem disappears.

In the first image the three vertical lines, the edge boundaries of the nested frames, need to appear as one line (the same thing applies to the horizontal lines at the bottom of the image). The desired result is a (parent) frame that contains 3 (child) frames - the second image.

I have these nested frames : Merge these tkinter frame boundaries but need them to look like : Combined tkinter Frame Boundaries

BTW, all three child frames were implemented as Frame, not Button widgets.

I've tried playing around with the "padx" (zero and negative numbers), "relief" (set to FLAT, etc.), and borderwidth (set to 0 and -1) widget properites without success.

I'm reluctant to re-engineer the app (to use Canvas and/or ttk.Separator) just to fix this small but annoying issue. And eliminating the nesting is NOT an acceptable approach (unless there's absolutely no other way).

Any suggestions?

1
Show us a minimal reproducible example so we can play with it. I'm guessing the easiest solution will be to make a function to convert from nested to sequential. - Novel
What do you mean by nested exactly? What's the kind of nesting that you don't want to eliminate unless there's absolutely no other way? - Stop harming Monica
Frame A contains Frame B which contains Frame C. Complexity is managed by placing each frame in it's own (nested) function. "Unnesting" destroys the modularity/isolaton enforced by this structure, making the code harder to maintain (you go from a clean structure to a messy one). The screenshots are extremely simplifed versions of what's in each frame which is why easy maintenance/modification is a basic requirement (e.g. you can move a child frame to a different parent just by moving the function call to the new parent). - user1459519

1 Answers

2
votes

Setting the borderwidths of the inner frames to zero and then separating them with a ttk.Separator gives you the look you want.

enter image description here

Code that produced the above image:

import tkinter as tk
from tkinter import ttk

root = tk.Tk()
root.geometry("250x200")

outer_frame = tk.Frame(root, borderwidth=2, relief="groove")
outer_frame.pack(side="top", fill="both", expand=True, padx=20, pady=20)

f1 = tk.Frame(outer_frame, borderwidth=0, highlightthickness=0)
f2 = tk.Frame(outer_frame, borderwidth=0, highlightthickness=0)
f3 = tk.Frame(outer_frame, borderwidth=0, highlightthickness=0)

tk.Label(f1, text="Child Frame 1").pack(fill="both", expand=True)
tk.Label(f2, text="Child Frame 2").pack(fill="both", expand=True)
tk.Label(f3, text="Child Frame 3").pack(fill="both", expand=True)

s1 = ttk.Separator(outer_frame, orient="horizontal")
s2 = ttk.Separator(outer_frame, orient="horizontal")

f1.pack(side="top", fill="both", expand=True)
s1.pack(side="top", fill="x", expand=False)
f2.pack(side="top", fill="both", expand=True)
s2.pack(side="top", fill="x", expand=False)
f3.pack(side="top", fill="both", expand=True)

root.mainloop()