Skip to content
Advertisement

Tkinter – How to create a custom Tkinter Frame object? I tried but it doesn’t work

I tried to create some custom tkinter objects to build my GUIs easier but unfortunately I couldn’t. For example, what about if I want an object that identify a frame placed inside another one? To do that I wrote it:

Main code (file name: test.py):

import tkinter as tk
from tkinter import ttk
import ttk_plus as ttkp # my custom library

parent=tk.Tk()
parent.geometry("686x424+370+100")
parent.title("Test")
parent.configure(background="#f0f0f0")
parent.minsize(686, 424)

MyFrame=ttkp.Frame(parent) # my custom object
MyFrame.pack(padx=(5,5), pady=(5,5))

parent.mainloop() 

Library (file name: ttk_plus.py):

class Frame(tk.Frame):
    def __init__(self, container):
        super().__init__(container)
        
        self.container=container
        
        # definisco il frame principale:
        self.Frame1=tk.Frame(self.container, background="white")
        
        # definisco il frame secondario:
        self.Frame2=tk.Frame(self.Frame1, background="white", highlightbackground="red", highlightthickness=1)
        self.Frame2.pack(padx=(5, 5), pady=(5, 5), fill=tk.BOTH)

If I run test.py, the software start without any kind of issues, but I can’t see my object inside the main window. Where did I go wrong?

Advertisement

Answer

If you are creating a custom frame, every widget created in this frame needs to be a descendant of the frame, not the container. Otherwise, Frame will affect its parent in unexpected ways.

self.Frame1=tk.Frame(self, background="white")

You also need to make sure you call some geometry manager (pack, place, grid) on this inner frame. Otherwise, this frame and any widgets in it won’t be visible.

Since it’s the only direct child in the container, pack is the simplest:

self.Frame1.pack(fill="both", expand=True)

Finally, since at the moment you’re only creating frames, you’ll likely want to either give the frame a size, or use geometry manager attributes that cause it to fill the window.

MyFrame.pack(padx=(5,5), pady=(5,5), fill="both", expand=True)
User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement