pythonoopinheritance

How do I change a variable while inheriting?


I'm using OOP for the first time, I want to make the SubWindow class inherit all properties from the MainWindow class, but self.root would be tk.Toplevel() instead of tk.Tk():

import tkinter as tk

class MainWindow:
    def __init__(self, size, title):
        self.root = tk.Tk()
        self.root.geometry(size)
        self.root.title(title)
        
    def packAll(self):
        for widget in self.root.children:
            self.root.children[widget].pack()
            
class SubWindow(MainWindow):
    def __init__(self, size, title):
        super().__init__(size, title)

If I put self.root = tk.Toplevel() after super().__init__(size, title), it still creates another instance of tkinter. Private variables haven't worked either. I haven't found a solution online. How do I solve this?


Solution

  • What you can do is to pass a required value for self.root to the base class constructor, with a default where the base class chooses tk.Tk():

    import tkinter as tk
    
    class MainWindow:
        def __init__(self, size, title, root=None):
            if root == None:
                root = tk.Tk()
            self.root = root
            self.root.geometry(size)
            self.root.title(title)
            
        def packAll(self):
            for widget in self.root.children:
                self.root.children[widget].pack()
                
    class SubWindow(MainWindow):
        def __init__(self, size, title):
            super().__init__(size, title, tk.Toplevel())
    

    This way only one root is instantiated, occurring before geometry() and title() are called.

    But, really, you shouldn't have to have if statements when you can just pass in the right values:

    import tkinter as tk
    
    class Window:
        def __init__(self, root, size, title):
            self.root = root
            self.root.geometry(size)
            self.root.title(title)
            
        def packAll(self):
            for widget in self.root.children:
                self.root.children[widget].pack()
                
    class MainWindow(Window):
        def __init__(self, size, title):
            super().__init__(tk.Tk(), size, title)
    
    class SubWindow(Window):
        def __init__(self, size, title):
            super().__init__(tk.Toplevel(), size, title)