Search code examples
pythonkivykivy-language

Kivy: Pass kwarg to a child widget defined in Kv (when initialising)


Suppose I have a simple widget that counts clicks:

<ClickCounter>: # BoxLayout
    amount: 1
    Label:
        text: amount
    Button:
        text: '+1'
        on_release: root.amount += 1

I want to use this widget elsewhere in my app, e.g.:

<ParentWidget>: # BoxLayout
    Label:
        text: 'The widget below will count your clicks:'
    ClickCounter:
        id: counter

In my python code, I want to do ParentWidget(amount=5), i.e. I want to the ClickCounter inside ParentWidget to start counting at 5. How can I do this?

My tries

This would works, but it’s ugly and updates the value the next frame:

class ParentWidget(BoxLayout):
    def __init__(self, *args, **kwargs):
        amount = kwargs.pop('amount', 0)
        super(ParentWidget, self).__init__(*args, **kwargs)
        
        Clock.schedule_once(lambda dt: self.ids.counter.amount = amount)

or maybe something like this, but the property would be used only for initialisation, which is equally ugly:

<ParentWidget>
    amount: 0
    # …
    ClickCounter:
        amount: root.amount

Solution

  • There is no kv language syntax for passing kwargs to a widget that is instantiated as part of a kv rule. Do what you want using properties, or invent a different control flow, or both.