pythontkintermultiple-inheritancetoplevel

Subclass of tkinter's Toplevel class doesn't seem to inherit "tk" attribute


I'm writing a Python application using tkinter GUI. I created the TimestampWindow class which should be one of my Windows and made it extend the Toplevel class of tkinter's library and Window, a custom class where I put common attributes/methods for all my Windows. Unfortunately when I try to call self.title(...) on Window class (from a TimestampWindow instance) I get the following error:

File "/home/ela/elaPythonVirtualENV/PythonScripts/pgnclocker/pgnClocker/gui/windows/Window.py", line 54, in setUp
  self.title(CommonStringsEnum.APP_NAME.value)     
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.12/tkinter/__init__.py", line 2301, in wm_title
  return self.tk.call('wm', 'title', self._w, string)
       ^^^^^^^
AttributeError: 'TimestampWindow' object has no attribute 'tk'

Things doesn't change if I move the invocation of title method directly in TimestampWindow.

I leave two snippets with a "sketch" of TimestampWindow and Window classes below to clarify the whole thing:

Timestamp Window

import tkinter as tk
from pgnClocker.gui.windows.Window import *
... more imports ...

class TimestampWindow(tk.Toplevel, Window):

    ... code ...

Window

class Window:

    ... code ...

    def setUp(self):
        self.title(CommonStringsEnum.APP_NAME.value)     

Could you please help me understand what's going on here? Shouldn't I be able to use TimestampWindow as a tkinter window since it inherits all methods from tk.Toplevel? Why it isn't inheriting tk attribute?


Solution

  • tk is an attribute of the root window. To access it, you need to pass the master to your class.

    import tkinter as tk
    
    
    class Window:
    
        def setUp(self):
            self.title("Title")
    
    
    class TimestampWindow(tk.Toplevel, Window):
        
        def __init__(self, master): # <-
            super().__init__(master) # <-
            print("master:", master, master.call)
            print("self.tk:", self.tk, self.tk.call)
            #master.call('wm', 'title', self, "New title")
            self.tk.call('wm', 'title', self, "New title")
            self.transient(master)
            #self.setUp()
    
    root = tk.Tk()
    print("root.tk:", root.tk, root.tk.call)
    root.title("Root")
    t = TimestampWindow(root) # <-
    root.mainloop()