I added a FloatButton on my screen, but I am unable to associate any on_release actions to it. I suspect the issue is linked to the fact that my FloatButton actually inherits from FloatLayout, so it does not have the on_release property? Here is my FloatButton definition in the kv file:
<FloatButton@FloatLayout>:
id: float_add_button # Giving id to button
size_hint: (None, None)
text: ''
btn_size: (70, 70)
size: (70, 70)
bg_color: (0.404, 0.227, 0.718, 1.0)
# pos_hint: {'x': .6}
Button:
text: float_add_button.text
markup: True
font_size: 40
size_hint: (None, None)
size: float_add_button.btn_size
pos_hint: {'x': .5, 'y': .8}
background_normal: ''
background_color: (0, 0, 0, 0)
canvas.before:
Color:
rgba: (0.404, 0.227, 0.718, 1.0)
Ellipse:
size: self.size
pos: self.pos
and further down the kv file I assing on_release
<MainWindow>:
name: 'main'
RelativeLayout:
orientation: 'lr-tb'
size_hint: 1, 1
padding: '20sp'
canvas.before:
Rectangle:
pos: self.pos
size: self.size
# A few buttons here
#
#
#
FloatButton:
id: addButton
text: '+'
markup: True
background_color: 1, 0, 1, 0
pos_hint: {"x":.5,"top":.5}
on_release:
print("[TEST] on_release works!")
However, I get the following error:
Traceback (most recent call last):
File "C:\Users\gitcanzo\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\LocalCache\local-packages\Python311\site-packages\kivy\lang\builder.py", line 734, in _apply_rule
raise AttributeError(key)
AttributeError: release
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "D:\Recipy_project\Recipy\main.py", line 1, in <module>
from Recipy.app import Recipy
File "D:\Recipy_project\Recipy\Recipy\app.py", line 21, in <module>
kv = Builder.load_file("Recipy/ui/layout.kv")
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\gitcanzo\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\LocalCache\local-packages\Python311\site-packages\kivy\lang\builder.py", line 310, in load_file
return self.load_string(data, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\gitcanzo\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\LocalCache\local-packages\Python311\site-packages\kivy\lang\builder.py", line 412, in load_string
self._apply_rule(
File "C:\Users\gitcanzo\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\LocalCache\local-packages\Python311\site-packages\kivy\lang\builder.py", line 665, in _apply_rule
child.apply_class_lang_rules(
File "C:\Users\gitcanzo\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\LocalCache\local-packages\Python311\site-packages\kivy\uix\widget.py", line 470, in apply_class_lang_rules
Builder.apply(
File "C:\Users\gitcanzo\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\LocalCache\local-packages\Python311\site-packages\kivy\lang\builder.py", line 545, in apply
self._apply_rule(
File "C:\Users\gitcanzo\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\LocalCache\local-packages\Python311\site-packages\kivy\lang\builder.py", line 741, in _apply_rule
raise BuilderException(
kivy.lang.builder.BuilderException: Parser: File "D:\Recipy_project\Recipy\Recipy\ui\layout.kv", line 590:
...
588: pos_hint: {"x":.5,"top":.5}
589: on_release:
>> 590: print("[TEST] on_release works!")
591: # root.manager.transition.direction = "left"
592: # app.root.current = 'add'
...
AttributeError: release
File "C:\Users\gitcanzo\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\LocalCache\local-packages\Python311\site-packages\kivy\lang\builder.py", line 734, in _apply_rule
raise AttributeError(key)
The cause of the problem is exactly what you say, your FloatButton
class is derived from FloatLayout
not from Button
, so it does not have the on_release
event.
One option is to define that custom event in your FloatButton
class:
class FloatButton(FloatLayout):
def __init__(self, *args, **kwargs):
self.register_event_type('on_release')
super().__init__(*args, **kwargs)
def on_release(self, *args):
pass
and dispatch it when the internal button is pressed:
<FloatButton@FloatLayout>:
# ...
Button:
on_release: root.dispatch('on_release')
A complete reproducible example:
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.floatlayout import FloatLayout
kv = '''
<FloatButton@FloatLayout>:
id: float_add_button # Giving id to button
size_hint: (None, None)
text: ''
btn_size: (70, 70)
size: (70, 70)
bg_color: (0.404, 0.227, 0.718, 1.0)
# pos_hint: {'x': .6}
Button:
on_release: root.dispatch('on_release')
text: float_add_button.text
markup: True
font_size: 40
size_hint: (None, None)
size: float_add_button.btn_size
pos_hint: {'x': .5, 'y': .8}
background_normal: ''
background_color: (0, 0, 0, 0)
canvas.before:
Color:
rgba: (0.404, 0.227, 0.718, 1.0)
Ellipse:
size: self.size
pos: self.pos
<MainWindow@RelativeLayout>:
name: 'main'
FloatButton:
id: addButton
text: '+'
markup: True
background_color: 1, 0, 1, 0
pos_hint: {"right":.5,"top":.5}
on_release:
print("[TEST] on_release works!")
MainWindow:
'''
class FloatButton(FloatLayout):
def __init__(self, *args, **kwargs):
self.register_event_type('on_release')
super().__init__(*args, **kwargs)
def on_release(self, *args):
pass
class MainWindow(App):
def build(self):
return Builder.load_string(kv)
if __name__ == '__main__':
MainWindow().run()