Reputation: 31
I'm a newbie in Python and to learn more about OOP. I want to create a new button class based on toga.Button
. I used the example on the Toga website and added a new class based on the toga.Button
class. Initially, I would like the behaviour of this dervived class to be the same as the original class. However, when running the code I get an error.
The code is as follows:
import toga
def button_handler(widget):
print("hello")
class ColorButton(toga.Button):
def init(self, *args):
super().init(*args)
def on_press(self, *args, **kwargs):
super().on_press(*args, **kwargs)
def build(app):
box = toga.Box()
button = toga.Button("Hello world", on_press=button_handler)
button.style.padding = 50
button.style.flex = 1
box.add(button)
button1 = ColorButton("Hello world1", on_press=button_handler)
button1.style.padding = 50
button1.style.flex = 1
box.add(button1)
return box
def main():
return toga.App("First App", "org.beeware.toga.tutorial", startup=build)
if name == "main":
main().main_loop()
Running the code give the following error:
Traceback (most recent call last): File "\\app\\ttt_main\_.py", line 4,
in \<module\> main().main_loop() File "\\app_packages\\toga\\app.py", line 619,
in main_loop self.\_impl.main_loop() File "\\app_packages\\toga_winforms\\app.py", line 302,
in main_loop raise self.\_exception File "\\app_packages\\toga_winforms\\app.py", line 277,
in \_run_app self.create() File "\\app_packages\\toga_winforms\\app.py", line 148,
in create self.interface.\_startup() File "\\app_packages\\toga\\app.py", line 641,
in \_startup self.startup() File "\\app_packages\\toga\\app.py", line 654,
in startup self.main_window.content = self.\_startup_method(self) File "\\app\\ttt\\app.py", line 21,
in build button1 = ColorButton("Hello world1", on_press=button_handler)
TypeError: init() got an unexpected keyword argument 'on_press'
I would liked to have seen two buttons with similar behaviour.
Upvotes: 1
Views: 86
Reputation: 653
Functions can take arguments and keyword arguments.
A function can take a list of arguments, when you prefix the argument with a *
, e.g. *args
, as you already do. This variable will hold a tuple of the collected arguments.
Similarly, a function can take keyword arguments when you prefix an argument with **
, e.g. **kwargs
. This variable will hold a dictionary with the keys and their associated values ("on_press"
and button_handler
in your case).
The same applies for unpacking: tuples with *
and dictionaries with **
.
So your current ColorButton.__init__
method only takes arguments and no keyword arguments. It can't take arguments. If it would, the values were not associated with their keys in the args
tuple.
Therefore just add **kwargs
to your ColorButton.__init__
method:
class ColorButton(toga.Button):
def init(self, *args, **kwargs):
super().init(*args, **kwargs)
But if you don't intend to change or add anything to this method, there's no benefit in overwriting it. You can just leave it out.
Upvotes: 0