How to create a subclass of ttk.Button correctly (class function doesnt work)?

Question:

I want to create Buttons with a text and define a function that prints me the text on the monitor when i press the button.

Everything works well without classes:

from tkinter import *
from tkinter import ttk

def PressButton():
    print(FirstButton.cget('text'))

root = Tk()
root.title("Simple Calculator")

ButtonsFrame = ttk.Frame(root,relief= "groove").grid()
FirstButton=ttk.Button(ButtonsFrame, text=1, command= PressButton)
FirstButton.grid()

root.mainloop()

"1" is printed on the monitor when I press FirstButton.
Because I want to have a lot of Buttons, I created a class MyButton with the parent ttk.Button:

from tkinter import *
from tkinter import ttk

class MyButton(ttk.Button):
    def __init__(self, text):
        self.text=text
        super().__init__()
        self.Button=ttk.Button(ButtonsFrame, text=self.text, command=self.PressButton)
    def PressButton(self):
        print(self.Button.cget('text'))

root = Tk()
root.title("Simple Calculator")

ButtonsFrame = ttk.Frame(root,relief= "groove").grid()
FirstButton=MyButton(1)
FirstButton.grid()

root.mainloop()

Here a button is created but without text at all.
I found out that if I change the super().__init__() to super()._init__(text=self.text) then I get a Button with the right text but the PressButton command doesnt work. I tried diffent things with *args aswell but had no success.

What am I doing wrong? I would appreciate any help.

Asked By: Alexej Rausch

||

Answers:

The main problem is that you’re not specifying the parent widget for the parent in the constructor.

Here’s corrected version of code:

from tkinter import *
from tkinter import ttk

class MyButton(ttk.Button):
    def __init__(self, parent, text):
        self.text=text
        super().__init__(parent, text=self.text, command=self.PressButton)
    def PressButton(self):
        print(self.cget('text'))

root = Tk()
root.title("Simple Calculator")

ButtonsFrame = ttk.Frame(root,relief= "groove").grid()
FirstButton=MyButton(ButtonsFrame, 1)
FirstButton.grid()

root.mainloop()

You could’ve also swapped super(). with this:

super(MyButton,self).__init__(parent, text=self.text,command=self.PressButton)

Which is equal to super().__init__(parent, text=self.text, command=self.PressButton)

You can read more about it here:
https://docs.python.org/3/library/functions.html#super

Answered By: str1ng