0

In a different question about the structure of Python code one solution was proposed: The question is here to be found: Best way to structure a tkinter application

class Navbar(tk.Frame): ...
class Toolbar(tk.Frame): ...
class Statusbar(tk.Frame): ...
class Main(tk.Frame): ...

class MainApplication(tk.Frame):
    def __init__(self, parent, *args, **kwargs):
        tk.Frame.__init__(self, parent, *args, **kwargs)
        self.statusbar = Statusbar(self, ...)
        self.toolbar = Toolbar(self, ...)
        self.navbar = Navbar(self, ...)
        self.main = Main(self, ...)

        self.statusbar.pack(side="bottom", fill="x")
        self.toolbar.pack(side="top", fill="x")
        self.navbar.pack(side="left", fill="y")
        self.main.pack(side="right", fill="both", expand=True)

I like the solution and tried to replicate it on a tiny scale before applying it to my code. Can somebody please help me what arguments, parameters are missing to set up the application? See below my code:

import tkinter as tk


class Main(tk.Frame):

    def __init__(self, master):
        central = tk.Frame(master)
        central.pack(side="top", fill="both")

class SubMain(tk.Frame):

    def __init__(self,master):
        lowercentral = tk.Frame(master)
        lowercentral.pack(side="top", fill="both")

class MainApplication(tk.Frame):

    def __init__(self, parent):
        tk.Frame.__init__(self, parent)
        self.central = Main(self)
        self.lowercentral = SubMain(self)

        self.central.pack(side="top", fill="both")
        self.lowercentral.pack(side="top", fill="both")


root = tk.Tk()
MainApplication(root).pack(side="top", fill="both")
root.mainloop()

Few words to my code. I expect the code to basically just open an empty, white window. Class Main and SubMain should create two frames. MainApplication should integrate both classes and effectively act as the center of all classes.

However, I receive the error message:

AttributeError: 'Main' object has no attribute 'tk'

I assume, as in my example I am missing parameters in the init function of MainApplication but my variations did not yield any success.

Can somebody help me with this?

Alex_P
  • 2,580
  • 3
  • 22
  • 37

3 Answers3

2

First of all when you instantiate the Main and SubMain classes you need to pass the parent and not the MainApplication instance (self). Then you don't need to call the pack method on the classes, as both the Main and SubMain classes already pack their frame:

import tkinter as tk

class Main(tk.Frame):

    def __init__(self, master):
        central = tk.Frame(master)
        central.pack(side="top", fill="both")

class SubMain(tk.Frame):

    def __init__(self,master):
        lowercentral = tk.Frame(master)
        lowercentral.pack(side="top", fill="both")

class MainApplication(tk.Frame):

    def __init__(self, parent):
        tk.Frame.__init__(self, parent)
        self.central = Main(parent)
        self.lowercentral = SubMain(parent)

        #self.central.pack(side="top", fill="both")
        #self.lowercentral.pack(side="top", fill="both")


root = tk.Tk()
MainApplication(root)#.pack(side="top", fill="both")
root.mainloop()
toti08
  • 2,448
  • 5
  • 24
  • 36
  • Great! Thank you very much for your answer. It was, however, also possible to call super().__init__(). Your solutions works as well but does not use super(). What is better to do? (I prefer your solution because it saves me the pack().) I thought super() is used in situations of inheritance and therefore thought it would not be applicable in this scenario. – Alex_P Nov 08 '18 at 10:42
1

You could try this in init function:

 super().__init__(master)

I use it and it worked.Hope it valid.

M cache
  • 41
  • 7
1

Make sure to call super().__init__() in all of your __init__ functions. They are missing in Main and SubMain.

Theo Emms
  • 293
  • 1
  • 7