1

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.

  • 1
    `super().__init__()` (but with more arguments) is what initializes your instance as a `tk.Button`; you don't need to create a *second* instance explicitly. – chepner Feb 05 '23 at 15:29

1 Answers1

0

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

str1ng
  • 485
  • 3
  • 14
  • 1
    Hi str1ng, Thank you for your help. That actually solved the problem. Thank you for the link aswell. I appreciate the additional input. I tried to understand the discription but didnt get verything cause I am a Newbie to programming. Is it right if I say that all variables that are listed in brackets after 'super().__init__' override the variables in the original class? Furthermore: I dont have to create the 'ttk.Button' in '__init__' because if I call 'MyButton' it is an object of 'ttk.Button' anyways, correct? Why did you put 'parent' into the brackets? – Alexej Rausch Feb 05 '23 at 15:45
  • Yes, you're correct with that statement. `parent` is passed to the `super class constructor`, that way you're specifying the `parent widget` - which basically said, controls behavior and placement of its child widgets - therefore when you create a widget you need to specify the parent widget for it as it is responsible for controlling placement and behaviour of the child widget. When we passed `parent` to the `superclass constructor`, we specified `parent` widget that way you're actually creating button as a child of that widget. Hopefully this is clear enough for your. – str1ng Feb 05 '23 at 15:55
  • Also, I wasn't clear probably about your question "Why did you put `parent` into the brackets" - as I mentioned, it's all in order to achieve passing `parent` argument into the constructor of the parent class and specifying the parent widget. Basically, what we achieved here is a parent-child relationship between widgets. When you add a parent object to the 'super().init' function, you are giving information to the 'ttk.Button' class about what parent object it should be connected with. That's why 'parent' is included in the brackets. @AlexejRausch – str1ng Feb 05 '23 at 16:04
  • 1
    Alright, i am starting to understand something. Thank you for your time! @str1ng – Alexej Rausch Feb 05 '23 at 21:21