Search code examples
pythonkivykivymd

I am unable to display the ScrollView Widget inside a MDDialog Dialogbox of Kivymd


I am currently writing a program in which i want to display elements of a list inside a dialogbox. The problem i am facing is that the lists of the element aren't fully and not properly displayed in the dialogbox and i am unable to scroll and the button of the dialogbox becomes unclickable. i even tried the MDFloatLayout instead of the MDBoxLayout but then the elements overlap eachother and it still remains unscrollable and i still am unable to click the button of the dialogbox

This is my code:

from kivy.uix.button import Button
from kivymd.uix.boxlayout import MDBoxLayout
from kivy.uix.scrollview import ScrollView
from kivymd.app import MDApp
from kivymd.uix.dialog import MDDialog
from kivymd.uix.button import MDFlatButton
from kivymd.uix.label import MDLabel


class MyApp(MDApp):

    def build(self):
        self.match = [
            (1, 1, "First one", 0.9),
            (2, 2, "Second one", 0.8),
            (3, 3, "Third one", 0.7),
            (4, 4, "Fourth one", 0.6),
            (5, 5, "Last one", 0.5)
        ]

        return Button(text="Click me!", on_release=self.dialogbox)

    def dialogbox(self, *args):
        layout = MDBoxLayout()
        for e in range(5):
            label_text = "Place: {}\nNumber: {}\nName: {}\nPercentage: {}\n\n".format(
                self.match[e][0], self.match[e][1], self.match[e][2], self.match[e][3])
            label = MDLabel(text=label_text, size_hint_y=None, halign="left", valign="top")
            layout.add_widget(label)

        scroll_view = ScrollView()
        scroll_view.add_widget(layout)

        dialog = MDDialog(
            title="Title",
            buttons=[
                MDFlatButton(
                    text="Schließen",
                    on_release=lambda *args: dialog.dismiss()
                )
            ],
        )

        dialog.add_widget(scroll_view)
        dialog.open()


if __name__ == '__main__':
    MyApp().run()


Solution

  • You can use the content_cls property of the MDDialog to enable custom content of the dialog. And when you are using a ScrollView, you need to make the child of the ScrollView (in this case the MDBoxLayout) to use adaptive_height. And if the MDBoxLayout uses adaptive_height, then its children must must also use adaptive_height (or have a defined height).

    Here is a modified version of your dialogbox() method that does as described above:

    def dialogbox(self, *args):
        layout = MDBoxLayout(orientation='vertical', adaptive_height=True)  # set orientation and use adaptive_height
        for e in range(5):
            label_text = "Place: {}\nNumber: {}\nName: {}\nPercentage: {}\n\n".format(
                self.match[e][0], self.match[e][1], self.match[e][2], self.match[e][3])
            label = MDLabel(text=label_text, halign="left", valign="top", adaptive_height=True)
            layout.add_widget(label)
    
        dialog = MDDialog(
            title="Title",
            type="custom",
            content_cls=ScrollView(),  # set content of dialog to a ScrollView
            buttons=[
                MDFlatButton(
                    text="Schließen",
                    on_release=lambda *args: dialog.dismiss()
                )
            ],
        )
    
        dialog.content_cls.add_widget(layout)  # add the BoxLayout to the ScrollView
        dialog.update_height()  # update the dialog
        dialog.open()