7. Aggiunta Finestre di Dialogo (Pop-up)

Nella lezione precedente abbiamo aggiunto un menù di navigazione a scomparsa alla nostra applicazione WikipediaReader sviluppata con la libreria Kivy.

In questa ultima lezione su Kivy vedremo come aggiungere degli elementi al menù di navigazione implementato nella lezione precedente utilizzando il widget MDList di KivyMD.

Potete trovare il codice completo di Wikipedia Reader nel repository GitHub.


Come creare le voci del menù con il widget MDList di KivyMD

MDList viene utilizzato in combinazione con ScrollView (che abbiamo cominciato ad implementare nella lezione precedente) per fornire una lista di elementi scorrevoli all'interno dell'interfaccia utente. Si tratta di un widget estremamente flessibile e può essere utilizzato per visualizzare una vasta gamma di tipi di dati, come testo, immagini, icone e altro ancora.

Potete trovare la lista completa delle icone che rispettano le specifiche del Material Design di Google nella documentazione di KivyMD.

Modifichiamo il file wikireader.kv aggiungendo all’interno di ScrollView un widget MDList contenente due widget di tipo OneLineAvatarListItem in cui si può specificare un testo da mostrare e un’icona posizionata a sinistra utilizzando ImageLeftWidget. I due widget ci serviranno per mostrare le info dell’app e i contatti.

#:kivy 1.1.1

MDNavigationLayout:
    # ...

    MDNavigationDrawer:
        # ...

            ScrollView:

                MDList:

                    OneLineAvatarListItem:
                        text: "Info App"

                        IconLeftWidget:
                            icon: "information-outline"

                    OneLineAvatarListItem:
                        text: "Contattaci"

                        IconLeftWidget:
                            icon: "contact-mail-outline"

Se avviamo il nostro codice vedremo che il menù contiene i widget che abbiamo aggiunto, ma le icone non hanno ancora nessuna funzione associata. Adesso ci dedicheremo ad implementarli.


Come implementare pop-up contenenti informazioni sull’app e contatti

Andiamo nel nostro file main.py e creiamo due nuovi metodi che si occuperanno di mostrare nella schermata due finestre di dialogo: show_app_info_dialog, che gestirà quella contenente le informazioni relative all’applicazione, e show_contact_info_dialog, che gestirà quella per i contatti.

class WikiReaderApp(MDApp):
    # ...

    def show_app_info_dialog(self):
        pass

    def show_contact_info_dialog(self):
        pass

Modifichiamo anche entrambi i widget di MDList nel file wikireader.kv assegnando per entrambi alla variabile on_press la chiamata ai rispettivi metodi.

MDNavigationLayout:
    # ...

                MDList:

                    OneLineAvatarListItem:
                        text: "Info App"
                        on_press: app.show_app_info_dialog()

                        IconLeftWidget:
                            icon: "information-outline"

                    OneLineAvatarListItem:
                        text: "Contattaci"
                        on_press: app.show_contact_info_dialog()

                        IconLeftWidget:
                            icon: "contact-mail-outline"

Nel file main.py aggiungiamo l’import del widget MDDialog e aggiungiamo le due variabili info_dialog e contact_dialog alla classe WikiReaderApp assegnando loro il valore None:

# ...
from kivymd.uix.dialog import MDDialog


class WikiReaderApp(MDApp):

    info_dialog = None
    contact_dialog = None

Occupiamoci per prima cosa di implementare il metodo show_app_info_dialog. Facciamo in modo che se info_dialog non esiste il metodo lo crei utilizzando il widget MDDialog a cui dobbiamo passare come parametri il titolo della finestra di dialogo, il testo che contiene e se la finestra debba chiudersi quando l’utente fa clic su un’area al di fuori del pop up con auto_dismiss:

class WikiReaderApp(MDApp):

    # ...

    def show_app_info_dialog(self):
        app_info = "Wikipedia reader\n\nMade with <3"
        if not self.info_dialog:
            self.info_dialog = MDDialog(
                title = "Informazioni App",
                text = app_info,
                auto_dismiss = True
            )
        self.info_dialog.open()

In modo analogo implementiamo anche il metodo show_contact_info_dialog:

class WikiReaderApp(MDApp):

    # ...

    def show_contact_info_dialog(self):
        app_info = "Contatti:\n\nme@myself.com"
        if not self.contact_dialog:
            self.contact_dialog = MDDialog(
                title = "I Nostri Contatti",
                text = app_info,
                auto_dismiss = True
            )
        self.contact_dialog.open()

La nostra applicazione è completa! Adesso se eseguiamo il codice e selezioniamo le voci dal menù a scomparsa compariranno le finestre di dialogo:

kivy_lezione7

Codice del filemain.py

import certifi
from kivy.lang import Builder
from kivy.network.urlrequest import UrlRequest
from kivymd.app import MDApp
from kivymd.uix.dialog import MDDialog


class WikiReaderApp(MDApp):

    info_dialog = None
    contact_dialog = None

    def build(self):
        self.title = "WikipediaReader"
        self.theme_cls.primary_palette = "Teal"
        self.theme_cls.primary_hue = "400"
        return Builder.load_file("wikireader.kv")

    def normal_search_button(self):
        query = self.root.ids["mdtext"].text
        self.get_data(title=query)

    def random_search_button(self):
        endpoint = "https://it.wikipedia.org/w/api.php?action=query&list=random&rnlimit=1&rnnamespace=0&format=json"
        self.root.ids["mdlab"].text = "Caricamento in corso..."
        self.rs_request = UrlRequest(endpoint,
                                     on_success=self.get_data,
                                     ca_file=certifi.where())

    def get_data(self, *args, title=None):
        if title == None:
            response = args[1]
            random_article = response["query"]["random"][0]
            title = random_article["title"]
        endpoint = f"https://it.wikipedia.org/w/api.php?prop=extracts&explaintext&exintro&format=json&action=query&titles={title.replace(' ', '%20')}"
        self.data_request = UrlRequest(endpoint,
                                       on_success=self.set_textarea,
                                       ca_file=certifi.where())

    def set_textarea(self, request, response):
        page_info = response["query"]["pages"]
        page_id = next(iter(page_info))
        page_title = page_info[page_id]["title"]
        try:
            content = page_info[page_id]["extract"]
        except KeyError:
            content = f"Ci spiace, ma la ricerca '{page_title}' non ha prodotto risultati!\n\nRiprova! "
        self.root.ids["mdlab"].text = f"{page_title}\n\n{content}"

    def show_app_info_dialog(self):
        app_info = "Wikipedia reader\n\nMade with <3"
        if not self.info_dialog:
            self.info_dialog = MDDialog(
                title = "Informazioni App",
                text = app_info,
                auto_dismiss = True
            )
        self.info_dialog.open()

    def show_contact_info_dialog(self):
        app_info = "Contatti:\n\nme@myself.com"
        if not self.contact_dialog:
            self.contact_dialog = MDDialog(
                title = "I Nostri Contatti",
                text = app_info,
                auto_dismiss = True
            )
        self.contact_dialog.open()



WikiReaderApp().run()

Codice del filewikireader.kv

#:kivy 1.1.1

MDNavigationLayout:

    ScreenManager:

        Screen:

            BoxLayout:
                orientation: 'vertical'

                MDTopAppBar:
                    title: "Wikipedia Reader"
                    elevation: 10
                    left_action_items: [['menu', lambda x: nav_drawer.set_state()]]

                GridLayout:
                    rows: 4

                    MDTextField:
                        id: mdtext
                        hint_text: "Cosa Stai Cercando?"
                        mode: "rectangle"

                    MDRaisedButton:
                        text: "AVVIA RICERCA"
                        size_hint_x: 1
                        size_hint_y: 0.1
                        on_press: app.normal_search_button()

                    ScrollView:
                        MDLabel:
                            id: mdlab
                            text: "Benvenuti su Wikipedia Reader!"
                            size_hint_y: None
                            height: self.texture_size[1]
                            text_size: self.width, None

                    MDRaisedButton:
                        text: "CERCA ARTICOLO CASUALE"
                        size_hint_x: 1
                        size_hint_y: 0.1
                        on_press: app.random_search_button()

    MDNavigationDrawer:
        id: nav_drawer

        BoxLayout:
            orientation: "vertical"
            padding: "8dp"
            spacing: "8dp"

            AnchorLayout:
                anchor_x: "left"
                size_hint_y: None
                height: avatar.height

                Image:
                    id: avatar
                    size_hint: None, None
                    size: "56dp", "56dp"
                    source: "data/logo/kivy-icon-256.png"

            MDLabel:
                text: "WikiReader App 0.1"
                font_style: "Button"
                size_hint_y: None
                height: self.texture_size[1]

            MDLabel:
                text: "programmareinpython.it"
                font_style: "Caption"
                size_hint_y: None
                height: self.texture_size[1]

            ScrollView:

                MDList:

                    OneLineAvatarListItem:
                        text: "Info App"
                        on_press: app.show_app_info_dialog()

                        IconLeftWidget:
                            icon: "information-outline"

                    OneLineAvatarListItem:
                        text: "Contattaci"
                        on_press: app.show_contact_info_dialog()

                        IconLeftWidget:
                            icon: "contact-mail-outline"