Search code examples
pythonkivykivy-language

Kivy - Add others MDFloatingActionButton after touch


I'm trying to add the MDFloatingActionButton widget after clicking on button but I'm not getting it.

Someone could help me to solve this problem.

The goal is to create a list of buttons after clicking the FAB with the icon plus.

I tried adding code to add_widget() in a number of ways but none worked.

fab.py

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.properties import NumericProperty
from kivymd.theming import ThemeManager
from kivymd.time_picker import MDTimePicker
from kivymd.button import MDFloatingActionButton
from kivy.animation import Animation
from kivy.core.window import Window

Window.clearcolor = (1, 1, 1, 1)

class MDFloatingActionButtonList(MDFloatingActionButton):
    angle = NumericProperty(0)
    def on_touch_up(self, touch):
        if self.collide_point(*touch.pos):
            if self.angle == 0:
                self.angle += 45
                #MDFloatingActionButton.add_widget()
            else:
                self.angle -= 45

class Fab(App):
    theme_cls = ThemeManager()
    def build(self):
        return MDFloatingActionButtonList()    

Fab().run()

fab.kv

<MDFloatingActionButtonList>:
    canvas.before:                                                                                                                                             
        PushMatrix                                                                                                                                             
        Rotate:                                                                                                                                                
            angle: self.angle                                                                                                                                  
            axis: (0, 0, 1)                                                                                                                                    
            origin: self.center                                                                                                                                
    canvas.after:                                                                                                                                              
        PopMatrix
    MDFloatingActionButton:
        id: float_act_btn
        icon: 'plus'
        opposite_colors: True
        elevation_normal: 8
        pos_hint: {'center_x': 0.5, 'center_y': 0.2}

Result:

enter image description here

Goal for example:

enter image description here


Solution

  • Oh boy, this is a tough one. The KivyMD project is poorly documented, even though the design is so pretty.

    Ok, here is one example of how it might look:

    from kivy.app import App
    from kivy.core.window import Window
    from kivy.uix.boxlayout import BoxLayout
    
    from kivymd.button import MDFloatingActionButton
    from kivymd.menu import MDDropdownMenu
    from kivymd.theming import ThemeManager
    
    Window.clearcolor = (1, 1, 1, 1)
    
    menu_items = [
        {'viewclass': 'MDFloatingActionButton',
         'text': 'Example',
         'on_press': lambda: print("Hello")},
        {'viewclass': 'MDFloatingActionButton',
         'text': 'Example'},
        {'viewclass': 'MDFloatingActionButton',
         'text': 'Example'},
        {'viewclass': 'MDFloatingActionButton',
         'text': 'Example item'},
        {'viewclass': 'MDFloatingActionButton',
         'text': 'Example'},
        {'viewclass': 'MDFloatingActionButton',
         'text': 'Example'},
        {'viewclass': 'MDFloatingActionButton',
         'text': 'Example'},
    ]
    
    
    class Fab(App):
        theme_cls = ThemeManager()
        layout = BoxLayout()
        md = MDDropdownMenu(items=menu_items)
    
        def build(self):
            button = MDFloatingActionButton()
            self.layout.add_widget(button)
            button.bind(on_press=lambda x: self.md.open(button))
            return self.layout
    
    
    Fab().run()
    

    Pretty ugly

    Another way is to manually add the buttons to the window. But then you will have to handle the dissmiss (I did not implement it):

    from kivy.app import App
    from kivy.core.window import Window
    
    from kivymd.button import MDFloatingActionButton
    from kivymd.theming import ThemeManager
    
    Window.clearcolor = (1, 1, 1, 1)
    
    
    class Fab(App):
        theme_cls = ThemeManager()
        button = None
    
        def build(self):
            self.button = MDFloatingActionButton()
            self.button.bind(on_press=lambda x: self.open_menu(self.button))
            return self.button
    
        def open_menu(self, instance):
            x, y = instance.to_window(instance.x, instance.center_y)
    
            for i in range(1, 5):
                Window.add_widget(MDFloatingActionButton(center_y=y+100*i, x=x))
    
    
    Fab().run()
    

    Manually adding to a window