pythonkivymddialog

How can I add actions to the button in KivyMD MDDialog?


How can I add the action to the "OK" button ? I get a example code from KivyMd docs but there is no explanation how to add the acction to these buttons. Code :

from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout

from kivymd.app import MDApp
from kivymd.uix.button import MDFlatButton
from kivymd.uix.dialog import MDDialog

KV = '''
<Content>
    orientation: "vertical"
    spacing: "12dp"
    size_hint_y: None
    height: "120dp"

    MDTextField:
        hint_text: "City"

    MDTextField:
        hint_text: "Street"


FloatLayout:

    MDFlatButton:
        text: "ALERT DIALOG"
        pos_hint: {'center_x': .5, 'center_y': .5}
        on_release: app.show_confirmation_dialog()
'''


class Content(BoxLayout):
    pass


class Example(MDApp):
    dialog = None

    def build(self):
        return Builder.load_string(KV)

    def show_confirmation_dialog(self):
        if not self.dialog:
            self.dialog = MDDialog(
                title="Address:",
                type="custom",
                content_cls=Content(),
                buttons=[
                    MDFlatButton(
                        text="CANCEL", text_color=self.theme_cls.primary_color
                    ),
                    MDFlatButton(
                        text="OK", text_color=self.theme_cls.primary_color
                    ),
                ],
            )
        self.dialog.open()


Example().run()

After clicking "OK" I want to get the text from both MDTextField (City and Street). I think that I should make ids to these MDTextFields and add action (on_release) to the MDFlatButton with text="OK" but it does not help me. I would be grateful for any advice.


Solution

  • As you already mentioned, you can achive some click actions if you set a custom method to the on_press or on_release attributes of the MDFlatButtons.

    Reason:

    The reason why it was not working correctly was that the height of the dialog did not reach to the pos where the buttons have been set. I had to dig that out myself when setting custom methods to the on_press attribute did not work and close the dialog.

    Solution:

    Of course you can set a height yourself, but fortunately the MDDialog class has a method called set_normal_height() which is 80% of the window height, as you can see when you dive into the source code of kivymd. That is enough to include the button into the (not visible) area of the dialog.

    Now you can go on as you would usually and define custom methods which are called when the button is pressed or released. Here is a short example how you could get the textinputs value. You dont need the isinstance part when you assign ids for your textinputs, as you already mentioned yourself. The important part is that I inserted the self.dialog.set_normal_height() method right before the dialog is opened. I hope it works for you as well.

    Example:

    from kivy.lang import Builder
    from kivy.uix.boxlayout import BoxLayout
    
    from kivymd.app import MDApp
    from kivymd.uix.button import MDFlatButton
    from kivymd.uix.dialog import MDDialog
    from kivymd.uix.textfield import MDTextField
    
    KV = '''
    <Content>
        orientation: "vertical"
        spacing: "12dp"
        size_hint_y: None
        height: "120dp"
    
        MDTextField:
            hint_text: "City"
    
        MDTextField:
            hint_text: "Street"
    
    
    FloatLayout:
    
        MDFlatButton:
            text: "ALERT DIALOG"
            pos_hint: {'center_x': .5, 'center_y': .5}
            on_release: app.show_confirmation_dialog()
    '''
    
    
    class Content(BoxLayout):
        pass
    
    
    
    class Example(MDApp):
        dialog = None
    
        def build(self):
            return Builder.load_string(KV)
    
        def show_confirmation_dialog(self):
            if not self.dialog:
                self.dialog = MDDialog(
                    title="Address:",
                    type="custom",
                    content_cls=Content(),
                    buttons=[
                        MDFlatButton(
                            text="CANCEL", text_color=self.theme_cls.primary_color, on_release= self.closeDialog
                        ),
                        MDFlatButton(
                            text="OK", text_color=self.theme_cls.primary_color, on_release=self.grabText
                        ),
                    ],
                )
            self.dialog.set_normal_height()
            self.dialog.open()
    
    
        def grabText(self, inst):
            for obj in self.dialog.content_cls.children:
                if isinstance(obj, MDTextField):
                    print(obj.text)
            self.dialog.dismiss()
    
        def closeDialog(self, inst):
            self.dialog.dismiss()
    
    
    Example().run()