3. Layout, Widget e Tasti Funzione

A partire da questa lezione utilizzeremo la libreria Kivy per Python per creare un’applicazione chiamata Wikipedia Reader in grado di scaricare articoli dal database di Wikipedia Italia connettendosi a un'API. Vedremo innanzitutto come creare il layout e come collegare funzionalità alla pressione di tasti.

Una volta completata, la nostra applicazione avrà due funzionalità principali: permetterà di visualizzare un articolo casuale alla pressione del tasto nella parte inferiore della pagina e di cercare un articolo specifico tramite la barra di ricerca e un altro tasto nella parte superiore. L’app avrà anche un menù a comparsa in alto a sinistra con le impostazioni, le ricerche salvate, le info sull’app e i contatti.

Potete trovare il codice di Wikipedia Reader nel repository Github.


La palette di colori di KivyMD

Cominciamo creando lo scheletro della nostra applicazione come abbiamo visto nella lezione introduttiva: creiamo un nuovo file chiamato main.py, importiamo MDApp e Builder, creiamo la nostra classe principale e implementiamo il metodo build per definire un titolo e analizzare la stringa KV che andremo a definire.

from kivymd.app import MDApp
from kivy.lang import Builder


KV = """

"""

class WikiReaderApp(MDApp):

    def build(self):
        self.title = "WikipediaReader"
        return Builder.load_string(KV)

WikiReaderApp().run()

Decidiamo inanzitutto uno stile per la nostra applicazione: KivyMD fornisce una vasta gamma di nomi di colori predefiniti che possono essere utilizzati per definire l’aspetto degli elementi grafici all'interno delle applicazioni. Questi nomi sono organizzati in gruppi che rappresentano diverse tonalità e intensità: ad esempio, il gruppo "Red" comprende tonalità di rosso che vanno dal più scuro al più chiaro. Ecco la lista dei nomi di colori predefiniti in KivyMD:

kivymd.color_definitions.palette = ['Red', 'Pink', 'Purple', 'DeepPurple', 'Indigo', 'Blue', 'LightBlue', 'Cyan', 'Teal', 'Green', 'LightGreen', 'Lime', 'Yellow', 'Amber', 'Orange', 'DeepOrange', 'Brown', 'Gray', 'BlueGray']

Per fare riferimento ai colori, oltre ai nomi predefiniti è possibile utilizzare anche i valori esadecimali e RGB. Per definire la tonalità dei colori nella palette predefinita possiamo specificare anche un parametro il valore hue tra quelli che seguono:

kivymd.color_definitions.hue = ['50', '100', '200', '300', '400', '500', '600', '700', '800', '900', 'A100', 'A200', 'A400', 'A700']

Specifichiamo quindi una palette di colori per la nostra applicazione tramite primary_palette e scegliamo anche una tonalità tramite primary_hue.

class WikiReaderApp(MDApp):

    def build(self):
        self.title = "WikipediaReader"
        self.theme_cls.primary_palette = "Indigo"
        self.theme_cls.primary_hue = "400"


Aggiungiamo dei widget: l’etichetta MDLabel e il tasto MDRaisedButton

Definiamo la stringa multiriga KV aggiungendo come elemento principale il widget Screen.

Kivy mette a disposizione diversi tipi di layout che possono essere utilizzati per organizzare gli elementi dell'interfaccia utente: potete vedere un’immagine animata che li descrive nella documentazione di Kivy. Noi utilizzeremo il GridLayout, che permette di organizzare i widget in una griglia con righe e colonne, aggiungiamolo all’interno di screen tramite l’indentazione e definiamo il numero di righe assegnando un valore a rows:

KV = """
Screen:
    GridLayout:
        rows: 2

"""

Nelle due righe che abbiamo definito per il nostro layout posizioneremo un tasto e un’etichetta per renderizzare del testo sulla nostra finestra.

Aggiungiamo un etichetta inserendo il widget MDLabel alla griglia specificando un id e il testo che deve mostare impostando le proprietà degli identificatori id e text:

KV = """
Screen:
    GridLayout:
        MDLabel:
            id: mdlab
            text: "Benvenuti su Wikipedia Reader!"
"""

Inseriamo un pulsante nella seconda riga della nostra griglia aggiungendo sullo stesso livello di indentazione di MDLabel il widget MDRaisedButton e specificando le sue proprietà id e text come abbiamo fatto con l’etichetta.

KV = """
Screen:
    GridLayout:
        MDLabel:
            id: mdlab
            text: "Benvenuti su Wikipedia Reader!"

        MDRaisedButton:
            id: mdbu
            text: "PREMI QUESTO TASTO!"
"""

Specifichiamo che il testo dell’etichetta MDLabel deve essere un titolo h1 aggiungendo l’apposito identificatore font_style e 30px di padding orizzontale:

KV = """
Screen:
    GridLayout:
        MDLabel:
            id: mdlab
            text: "Benvenuti su Wikipedia Reader!"
            font_style: "H1"
            padding_x: 30
"""


Come far compiere un'azione al pulsante MDRaisedButton

Se eseguiamo il programma vedremo il pulsante in basso a sinistra con una larghezza pari a quella del testo che contiene. Possiamo modificare le dimensioni degli elementi della nostra app specificando le proprietà size_hint_x e size_hint_y, che seguono il sistema di coordinate normalizzato di Kivy che abbiamo visto nella prima lezione riguardo a pos_hint. Per fare in modo che la lunghezza del pulsante si estenda per la lunghezza del widget che lo contiene impostiamo 1 come valore per size_hint_x:

KV = """
# ...
        MDRaisedButton:
            id: mdbu
            text: "PREMI QUESTO TASTO!"
            size_hint_x: 1
"""

Abbiamo detto che premendo il pulsante pulsante la nostra app dovrà mostrare una pagina casuale di Wikipedia Italia: per specificare quale azione dovrà essere eseguita alla pressione del pulsante assegniamo alla proprietà on_press il metodo della classe WikiReaderApp che creeremo tra poco: random_search_button:

KV = """
# ...
        MDRaisedButton:
            id: mdbu
            text: "PREMI QUESTO TASTO!"
            size_hint_x: 1
            on_press: app.random_search_button()
"""

Creiamo quindi il metodo random_search_button e per il momento facciamo in modo che compaia una scritta sulla nostra etichetta MDLabel riferendoci ad essa tramite l’id che abbiano definito nella stringa KV:

class WikiReaderApp(MDApp):
    # ...

    def random_search_button(self):
        self.root.ids["mdlab"].text = "Tasto ricerca casuale premuto!"


WikiReaderApp().run()


Come implementare lo scrolling del testo dell’articolo con ScrollView

Dal momento che i sommari e gli articoli di Wikipedia sono spesso molto lunghi dobbiamo implementare lo scrolling. Aggiungiamo un ulteriore contenitore per l’etichetta aggiungendo il widget ScrollView sullo stesso livello di indentazione di MDRaisedButton. Da MDLabel rimuoviamo font_style e padding_x, aggiungiamo size_hint_x impostandolo su None e aggiungiamo la proprietà height impostandola su self.texture_size[1]: questo farà in modo che il testo cominci dalla parte superiore della schermata ma avendo a disposizione tutto lo spazio verticale possibile.

from kivymd.app import MDApp
from kivy.lang import Builder


KV = """
Screen:
    GridLayout:
        rows: 2
        ScrollView:
            MDLabel:
	              # ...
                size_hint_y: None
                height: self.texture_size[1]
        MDRaisedButton:
                # ...
"""

Infine aggiungiamo la proprietà text_size assegnando come l’altezza self.width, per fare in modo che il contenuto si espanda per tutta la larghezza del widget, e come larghezza None per permettere lo scrolling. La nostra app dovrebbe apparire così:

kivy_lezione3

Ed ecco il nostro codice finora:

from kivymd.app import MDApp
from kivy.lang import Builder


KV = """
Screen:
    GridLayout:
        rows: 2
        ScrollView:
            MDLabel:
                id: mdlab
                text: "Benvenuti su Wikipedia Reader!"
                # font_style: "H1"
                # padding_x: 30
                size_hint_y: None
                height: self.texture_size[1]
                text_size: self.width, None
        MDRaisedButton:
            id: mdbu
            text: "PREMI QUESTO TASTO!"
            size_hint_x: 1 # 0.0 - 1.0
            on_press: app.random_search_button()
"""


class WikiReaderApp(MDApp):

    def build(self):
        self.title = "WikipediaReader"
        self.theme_cls.primary_palette = "Indigo"
        self.theme_cls.primary_hue = "400"
        return Builder.load_string(KV)

    def random_search_button(self):
        self.root.ids["mdlab"].text = "Tasto ricerca casuale premuto!"


WikiReaderApp().run()

Nella prossima lezione impareremo ad effettuare richieste di rete per ottenere gli articoli dal database di Wikipedia.