0

I am trying to create a Tkinter application using much cleaner formatting using inspiration from Bryan Oakley's suggestion from this post.

import tkinter as tk

class MainApplication(tk.Frame):
    def __init__(self, parent, *args, **kwargs):
        tk.Frame.__init__(self, parent, *args, **kwargs)
        self.parent = parent

        # Set start-up screen width and height
        screen_width = self.parent.winfo_screenwidth()
        screen_height = self.parent.winfo_screenheight()
        self.parent.geometry(f"{screen_width}x{screen_height}")

        # Adding Header
        self.header = Header(self)
        self.header.pack(side="top", fill="x")

class Header(tk.Frame):
    def __init__(self, parent):
        tk.Frame(parent, height=50, bg="#000000")



if __name__ == "__main__":
    root = tk.Tk()
    MainApplication(root).pack(side="top", fill="both", expand=True)
    root.mainloop()

However, when running this code, I get this error:

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

What am I doing wrong?

vexem
  • 86
  • 3

2 Answers2

1

tk.Frame in the Header class has no impact because the frame is not initialized with the class (tk.Frame) you are inheriting. hence when you use self.header.pack(side="top", fill="x") you are getting the error.You can use the below method which creates a frame object and places it in the init method. or you can add one more method inside the Header class which will return the frame object, thereby you can place it using pack in your MainApplication class

import tkinter as tk

class MainApplication(tk.Frame):
    def __init__(self, parent, *args, **kwargs):
        tk.Frame.__init__(self, parent, *args, **kwargs)
        self.parent = parent

        # Set start-up screen width and height
        screen_width = self.parent.winfo_screenwidth()
        screen_height = self.parent.winfo_screenheight()
        self.parent.geometry(f"{screen_width}x{screen_height}")
        Header(self.parent)


class Header(object):
    def __init__(self, parent):
        self.parent = parent
        self.frame = tk.Frame(self.parent, height=50, bg="#000000")
        self.frame.pack(side="top", fill="x")



if __name__ == "__main__":
    root = tk.Tk()
    MainApplication(root).pack(side="top", fill="both", expand=True)
    root.mainloop()
LiquidDeath
  • 1,768
  • 1
  • 7
  • 18
1

Your Header class isn't properly inheriting from tk.Frame. You need to make sure the __init__ method of the base class is called just like you do in MainApplication.

class Header(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)
        ...
Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
  • Bryan, `super()` was [added to Python 2.2](https://docs.python.org/3/whatsnew/2.2.html) in late December 2001, and it's now the last quarter of 2021 and Python 3.10 is available, so I humbly suggest you start using `super()` when defining subclasses. ;¬) – martineau Oct 16 '21 at 17:41
  • @martineau: yes, I know. I was being consistent with the rest of the code. – Bryan Oakley Oct 16 '21 at 17:51
  • I see, but note that the OP was only being consistent with an [answer of *yours*](https://stackoverflow.com/a/17470842/355230) dated Jul 4 '13 — so I guess it's not quite as much of an anachronism as I thought, but still… – martineau Oct 16 '21 at 17:59