简体   繁体   中英

How to make a subclass that fills *args and **kwargs of the parent?

I am trying to make a button subclass in tkinter so that it fills some of the args and kwargs automatically. I am not sure if it is a python issue or a tkinter issue.

from tkinter import *

root = Tk()

class MyButton(Button):
    def __init__(self, *args, **kwargs):
        super(Button).__init__(*args, **kwargs)

    kwargs = {"padx": 40, "pady": 20}
    args = (root)


test = Numbutton(text = "48")

test.pack()

root.mainloop()

And the error is:

Traceback (most recent call last):
  File "my file directory", line 18, in <module>
    test = Numbutton(text = "xyz", *args, **kwargs)
  File "my tkinter directory", line 1489, in cget
    return self.tk.call(self._w, 'cget', '-' + key)
TypeError: can only concatenate str (not "int") to str

Any help is appreciated :)

Here's a first stab:

from tkinter import *

root = Tk()

class MyButton(Button):
    def __init__(self, *args, **kwargs):
        super().__init__(root, padx=40, pady=20,**kwargs)

test = MyButton(text = "48")
test.pack()
root.mainloop()

EDIT:

here's a better way that can be used to used to make a subclass using the initial kwargs instead of hard coding initial kwargs:

from tkinter import Tk, Button


def set_button_initial(*initial_args, **initial_kwargs):
    class ButtonClassWithInitialStuff(Button):
        def __init__(self, *args, **kwargs):
            super().__init__(*initial_args, **initial_kwargs, **kwargs)
    return ButtonClassWithInitialStuff


root = Tk()

ButtonClass1 = set_button_initial(root, {"padx": 40, "pady": 20})
ButtonClass2 = set_button_initial(root, {"padx": 10, "pady": 50})

ButtonObject1a = ButtonClass1(text="48")
ButtonObject1b = ButtonClass1(text="49")
ButtonObject2 = ButtonClass2(text='second')
ButtonObject1c = ButtonClass1(text="50")

ButtonObject1a.pack()
ButtonObject1b.pack()
ButtonObject2.pack()
ButtonObject1c.pack()

root.mainloop()

Note, for the function set_button_initial we return the class ButtonClassWithInitialStuffinstead of an object ButtonClassWithInitialStuff(), that is, we set up the constructor (init), but we don't use it yet.

Using the function, we create classes ButtonClass1 and ButtonClass2.

Then, we instantiate obejcts ButtonObject1a-c and ButtonObject1 of our classes we just created. Note: we can reuse the classes to make as many objects as we want without re-calling set_button_initial

(edited to explain questions raised by commentors)

As far as I can see @MisterMiyagi suggests to use

from functools import partial

def set_button_initial(*initial_args, **initial_kwargs):
    return partial(Button, *initial_args, **initial_kwargs)

which appears to behave identically, but is nicer-looking without losing information, and is therefore better

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM