0

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()
6
  • Please update your question with a question. Commented Aug 8, 2021 at 19:06
  • 2
    The Button class shouldn't rely on the global root variable. Also you should call .pack/.grid/.place inside the Button class on the tk.Button Commented Aug 8, 2021 at 19:06
  • @quamrana From reading the code it looks like the button isn't going to appear on the screen. Commented Aug 8, 2021 at 19:06
  • 1
    Well, we might know just from looking what the code actually does, but the OP might have a different definition of having difficulty with tkinter. Commented Aug 8, 2021 at 19:08
  • 1
    @owwix your MainApplication class also shouldn't rely on the global variable root. Instead you should pass in self as in: self.button = Button(self). I will write an answer. Commented Aug 8, 2021 at 19:19

1 Answer 1

1

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

Sign up to request clarification or add additional context in comments.

8 Comments

Thank you so much! I need some clarification though. You said to note that "it doesn't really matter which one you choose." Do you mean it doesn't matter if I choose to pack or grid it or place it? Or that it doesn't matter whether I call .pack/.grid/.place in the Button class or MainApplication class? Because I noticed you packed the button in both classes, which is confusing me a little.
It doesn't matter if you used pack/grid/place inside the Button class on the tk.Button. I usually prefer using pack because it's easier to force widgets to expand. It's just a personal preference.
I see. Is there a reason you packed the button twice?
@owwix I packed it only once. Don't forget that in self.button = Button(self), self.button is actually from the Button class. So it's a tk.Frame not a tk.Button. Look at the class Button(tk.Frame). It forces the Button class to inherit from tk.Frame, therefore in the eyes of tkinter, it is a frame not a button.
@owwix Also I made a mistake an fixed my answer. I just noticed that I forgot to change tk.Button(root, text="Hello", width=25) => tk.Button(self, text="Hello", width=25)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.