I’m writing a custom widget for kivy(see this question), but I just found out that, for some unknown reason, sometimes the bind method does not actually bind the callbacks.
In my class I have this code:
def __init__(self, **kwargs):
super(SpinBox, self).__init__(**kwargs)
self._value_label = Label(text=str(self.value))
self.inc_button = TimedButton(text='+')
self.dec_button = TimedButton(text='-')
def inc(inst):
if float(self.value) + float(self.step) <= self.max_value:
self.value += self.step
def dec(inst):
if float(self.value) - float(self.step) >= self.min_value:
self.value -= self.step
self.inc_button.bind(on_press=inc)
self.inc_button.bind(on_time_slice=inc)
self.dec_button.bind(on_press=dec)
self.dec_button.bind(on_time_slice=dec)
# ...
Where TimedButton is an other custom class. It is a Button subclass that on on_touch_down starts a timer, if after a certain amount of time it didn’t receive a on_touch_up it consider the press a long-press and starts to dispatch the on_time_slice event using Clock.schedule_interval every some milliseconds.
So, trying to use my custom class like this:
class MyApp(App):
def build(self):
return SpinBox()
MyApp().run()
The value is not incremented at all.
If I do:
class MyApp(App):
def build(self):
s = SpinBox()
def inc(inst):
s.value += 1
s.inc_button.bind(on_time_slice=inc)
return s
MyApp().run()
The value is incremented at every on_time_slice event. I don’t understand why the bind inside the MyApp class works, while binding in the SpinBox.__init__ method does not.
What am I doing wrong?
I found a work around. Instead of binding the
on_touch_downandon_touch_upI tried to bind thestateproperty implementing anon_statemethod in theTimedButtonand it works. I still don’t understand why the previous implementation worked when used alone but not in theSpinBox, except when binding a function inside theAppclass directly.Anyway, since it looks like the
TimedButtonclass has something to do with it, here’s the code of the old implementation:And here’s the new code using
statewhich works perfectly well: