tkinter Root and Widget Sub-Classing (That works!)

In this guide we go over how to properly overload tkinter root and widget classes via 'side-loading' Tkinter has proven to be problematic and class examples are scarce on the internet.

tkinter Root and Widget Sub-Classing (That works!)

tkinter is a widget framework but beset with object problems.  Here is a working  example that will work reliably.

  • 'side-loading' is the preferred method that finally works. Using inheritance is always problematic. Therefore consider:
import time
import tkinter as tk
import os
from tkinter import *
from tkinter.ttk import *
import tkinter.ttk as ttk


class FCustomWidget:
    def __init__(self, x, y, width, height):

        self.widget = Canvas()
        self.widget.grid_forget()
        self.widget.config(background="#959595")
        self.widget.place(x=x, y=x, width=width, height=height)
        self.x = 5
        self.y = 5
        self.width = width
        self.height = height
        self.data = None

    def root_configure(self, width, height):
        self.x = 5
        self.y = 5
        self.width = width - 15
        self.height = height - 15
        self.widget.place(x=self.x, y=self.y, width=self.width, height=self.height)
        self.widget.update()


class FRootTester:

    def __init__(self, x, y, width, height):
        self.root = tk.Tk()

        self.root.title("Root tester")
        self.root.resizable(True, True)
        self.root.configure(background="#444444")
        self.widget = FCustomWidget(5, 5, 795, 595)

        self.x = x
        self.y = y
        self.width = width
        self.height = height

        self.root.bind("<Configure>", self.rootconfig)
        self.root.mainloop()


    def rootconfig(self, event):

        # Do NOT use event.width and event.height even though they are registered in the event as they do NOT
        # reflect the size of the root!
        width = self.root.winfo_width()
        height = self.root.winfo_height()

        x = event.x
        y = event.y

        if width != self.width or height != self.height:
            self.width = width
            self.height = height
            print("rootconfig: {x}, {y}, {width}, {height}".format(x=x, y=y, width=width, height=height))
            self.widget.root_configure(width, height)


FRootTester( 100, 100, 800, 600)

It should be noted - No parent passed!!!

self.widget = Canvas()  

However when it runs it properly assumes its child position inside the parent class of FRootTester.  

Will have proper resizing for absolute layouts (those who prefer it..)

Linux Rocks Every Day