owwix
owwix

Reputation: 73

Having trouble with Tkinter using OOP

I have created a small application in tkinter before using just top down programming but I am starting another project, this time using OOP and classes. But I'm having a hard time getting started, I just need someone to point me in the right direction. I've already dabbled in OOP with PyGame but I'm having difficulty with tkinter. Heres my code, where i'm just trying to display a button to the screen:

import tkinter as tk
from tkinter import ttk as ttk
import sqlite3

class Button(tk.Frame):
    def __init__(self):
        tk.Frame.__init__(self)
        tk.Button(root, text = "Hello", width = 25)

class MainApplication(tk.Frame):
    def __init__(self, parent, *args, **kwargs):
        tk.Frame.__init__(self, parent, *args, **kwargs)
        self.parent = parent
        self.button = Button()
        
        self.button.pack(side="bottom",fill="x")

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

Upvotes: 0

Views: 186

Answers (1)

TheLizzard
TheLizzard

Reputation: 7680

Try this:

import tkinter as tk
from tkinter import ttk # The `as tkk` isn't needed


# Here you might want to consider inheriting from `tk.Button` but it isn't going to change anything
class Button(tk.Frame):
    def __init__(self, master):
        tk.Frame.__init__(self, master)
        # It's always a good idea to keep a reference to all of your widgets
        self.button = tk.Button(self, text="Hello", width=25)
        # You should call `.pack`/`.grid`/`.place` here:
        # Note it doesn't really matter which one you choose
        self.button.pack(fill="both")

class MainApplication(tk.Frame):
    def __init__(self, parent, *args, **kwargs):
        tk.Frame.__init__(self, parent, *args, **kwargs)
        self.parent = parent # Technically this isn't needed because the line above sets `self.master` to parent

        self.button = Button(self) # Pass in self into the Button class
        self.button.pack(side="bottom", fill="x")


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

I passed in self when creating the Button object in self.button = Button() and I called self.button.pack(...) inside the Button class.

The whole point of OOP programming it to limit global variables and group similar objects in a single class definition. That is why both your Button and MainApplication classes shouldn't rely on root. Apart from that, your code is very nice :D

Upvotes: 1

Related Questions