Home > Gtk3, PyGObject, python > PyGObject: Gtk.ListBox

PyGObject: Gtk.ListBox

13 Aprile 2020

torna all’indice degli appunti

ListBox

Il widget Gtk.ListBox è un widget che contiene dei widget-figlio di tipo Gtk.ListBoxRow;
viene utilizzata quando vogliamo listare widget diversi tra loro, label, checkbutton ecc.
Queste rows (figli) possono essere anche ordinate e filtrate dinamicamente.

Per creare una ListBox si utilizza il costruttore Gtk.ListBox(**kwargs).
Come per tutti gli altri widgets visti fino ad ora, è possibile settare i parametri del widget
anche successivamente alla sua costruzione, con i soliti metodi getter e
setter get_property(property_name) e set_property(property_name, property_value):
La property più significativa è selection-mode, cioè un enum di tipo Gtk.SelectionMode
che può assumere i seguenti valori:

NONE (0): nessuna selezione possibile;
SINGLE (1): può essere selezionato 1 solo elemento, o nessuno;
BROWSE (2): può essere selezionato 1 solo elemento, ma è possibile anche deselezionarlo;
MULTIPLE (3): è possibile selezionare elementi multipli;

 
>>> import gi
... gi.require_version('Gtk', '3.0')
... from gi.repository import Gtk
>>> listbox = Gtk.ListBox()
>>> listbox.set_property("selection-mode", Gtk.SelectionMode.NONE)
>>> listbox.get_property("selection-mode")
<enum GTK_SELECTION_NONE of type Gtk.SelectionMode>

oppure con i metodi getter e setter specifici get_*property_name*() e
set_*property_name*(value).

Le properties principali di Gtk.ListBox sono:

Name Type Flags Short Description
activate-on-single-click bool r/w/en Attiva la row con singolo click
selection-mode Gtk.SelectionMode r/w/en Il tipo di selection mode

Segnali

I segnali principali sono:

Name Short Description
row-activated il segnale “row-activated” viene emesso quando una row viene attivata
row-selected il segnale “row-selected” viene emesso quando una nuova row viene selezionata, deselezionata
select-all il segnale “select-all” viene emesso quando tutti i children della listbox vengono selezionati (selection-mode = MULTIPLE)
selected-rows-changed il segnale “selected-rows-changed” viene emesso quando la selezione multipla cambia
unselect-all il segnale “unselect-all” viene emesso quando vengono deselezionati tutti i children della listbox, (selection-mode = MULTIPLE)

Metodi

Di seguito i metodi utilizzabili con il widget Gtk.ListBox:

new()

Metodo costruttore che crea un nuovo contenitore di tipo Gtk.ListBox

bind_model(model, create_widget_func, *user_data)

Lega la listbox a model, dove model è un oggetto di tipo Gio.ListModel.
Il precedente legame viene distrutto ed il contenuto della listbox, cancellato e nuovamente
riempito con gli elementi di model. Ogni volta che model cambia, la listbox viene aggiornata.
Se model=None, la listbox rimane vuota.
Utilizzare un model, è incompatibile con le funzionalità di filtering e sorting della listbox.
Tali funzionalità però possono essere implementate all’interno del model.
Parametri:
model: l’oggetto Gio.ListModel a cui legare la listbox, o None;
create_widget_func: una funzione che crei i widgets da utilizzare
come elementi, o None in caso model=None;
user_data: i dati da passare alla funzione create_widget_func;

drag_highlight_row(row)

Una funzione per implementare il Drag and Drop su una Gtk.ListBox.
La row passata come argomento verrà evidenziata con il metodo Gtk.Widget.drag_highlight() e
ogni row precedentemente evidenziata, tornerà nel suo stato “normale”.
Parametri:
row: un oggetto Gtk.ListBoxRow;

drag_unhighlight_row()

Se una row è stata precedentemente evidenziata via Gtk.ListBox.drag_highlight_row(),
tornerà al suo stato normale;

get_activate_on_single_click()

Ritorna True se la row viene attivata con un singolo click, altrimenti False.

get_adjustment()

Ritorna l’adjustment (se presente) che il widget usa con lo scrolling verticale.

get_row_at_index(index_)

Ritorna il child widget alla row index_, esclusa l’intestazione della listbox.
Se index_ è negatico o maggiore del numero di elementi della listbox, verrà ritornato None.
Parametri:
index_: l’indice (int) della row;

get_row_at_y(y)

Ritorna la row in posizione y.
Parametri:
y: la posizione (int) della row;

get_selected_row()

Ritorna la row selezionata.
In caso di selezione multipla, utilizzare il metodo selected_foreach() per
avere tutte le row selezionate

get_selected_rows()

Ritorna un oggetto di tipo GLib.List contenente tutti i children selezionati.
Una volta utilizzato l’oggetto, liberarlo con il metodo g_list_free().

get_selection_mode()

Ritorna il valore della property selection-mode.

insert(child, position)

Inserisce un child di tipo Gtk.Widget, alla posizione position.
Se si usa una funzione di sort, il child sarà inserito automaticamente alla giusta posizione.
Se position=-1 o è maggiore del numero di elementi nella listbox, il child sarà aggiunto alla fine (append).
Parametri:
child: l’oggetto Gtk.Widget da aggiungere alla listbox;
position: la posizione dove inserire il child;

invalidate_filter()

Aggiorna il filtering per tutte le rows. Questo metodo è utile quando il
risultato della funzione di filter è cambiato a causa di fattori esterni, ad esempio cambia il
contenuto della entry appena terminata la funzione di filter sul contenuto precedente della stessa.

invalidate_headers()

Aggiorna i separators per tutte le rows. Da utilizzare quando il risultato
della funzione di header è cambiato a causa di un fattore esterno.

invalidate_sort()

Aggiorna il sorting per tutte le rows.
Da utilizzare quando il risultato della funzione di sort è cambiato a causa di un fattore esterno.

prepend(child)

Aggiunge in capo alla listbox il child di tipo Gtk.Widget.
Se è stata settata una funzione di sort, il widget verrà automaticamente inserito nella posizione
corretta.
Parametri:
child: l’oggetto Gtk.Widget da aggiungere alla listbox;

select_all()

Seleziona tutti gli elementi della listbox.

select_row(row)

Seleziona il widget row.
Parametri:
row: l’oggetto Gtk.ListBoxRow da selezionare, o None

selected_foreach(func, *data)

Chiama la funzione func per ogni child selezionato.
All’interno di questa funzione non è possibile modificare la selezione.
Parametri:
func: un oggetto Gtk.ListBoxForeachFunc), ovvero
la funzione da chiamare per ogni child selezionato;
data: i parametri da passare alla funzione func;

set_activate_on_single_click(single)

Se single = True le rows saranno attivate con un singolo click, altrimenti sarà
necessario il double-click.

set_adjustment(adjustment)

Setta l’adjustment che il widget userà durante lo scrolling verticale.
Normalmente quando la listbox è inserita in un contenitore di tipo Gtk.ScrolledWindow,
l’adjustment sarà gestito automaticamente, pertanto non occorre gestirlo manualmente con questo
metodo.

set_filter_func(filter_func, *user_data)

Setta una funzione di filter per decidere quali elementi visualizzare nella listbox.
La funzione sarà chiamata per ogni row e continuerà ad essere invocata ogni volta che una row
cambia, grazie al metodo changed() dell’oggetto Gtk.ListBoxRow
(i children della listbox), o quando viene invocato il metodo invalidate_filter()
sulla listbox.
Nota: l’utilizzo di una funzione di filter è incompatibile con l’utilizzo di un model.
Parametri:
filter_func: l’oggetto Gtk.ListBoxFilterFunc, ovvero la callback
che permette di filtrare le rows o None;
user_data: i parametri da passare alla funzione filter_func;

set_header_func(update_header, *user_data)

Settando un funzione di header sulla listbox, possiamo dinamicamente aggiungere gli headers
alle rows, in base al loro contenuto e alla loro posizione. Ad esempio in una listbox ordinata
per tipo, possiamo aggiungere l’header di fronte alla row, ogni volta che si presenta un nuovo tipo.
update_header può controllare l’header widget corrente con il metodo
Gtk.ListBoxRow.get_header() ed eventualmente, sia aggiornare lo stato del widget,
sia settare un nuovo header con il metodo Gtk.ListBoxRow.set_header().
La funzione update_header sarà chiamata per ogni row e continuerà ad essere
invocata ogni volta che un row cambia, grazie al metodo Gtk.ListBoxRow.changed(),
quando la row precedente cambia o quando la row precedente diventa un row differente.
Viene infine chiamata quandi viene invocato il metodo Gtk.ListBox.invalidate_headers.
Parametri:
update_header: l’oggetto Gtk.ListBoxUpdateHeaderFunc, ovvero
la callback che permette di aggiungere gli headers, o None;
user_data: i parametri da passare alla funzione update_header;

set_placeholder(placeholder)

Setta il widget placeholder che viene visualizzato nella lista, quando nessun
children risulta visibile.

set_selection_mode(mode)

Setta la property selection-mode a mode.
Parametri:
mode: un oggetto Gtk.SelectionMode;

set_sort_func(sort_func, *user_data)

Settando una funzione di sort, possiamo dinamicamente riordinare le rows.
La funzione sort_func sarà chiamata per ogni row e continuerà ad essere invocata
ogni volta che la row cambia, grazie al metodo Gtk.ListBoxRow.changed(), o quando
viene chiamato il metodo Gtk.ListBox.invalidate_sort().
Nota: l’uso di una funzione di sort non è compatibile con l’utilizzo di un model.
Parametri:
sort_func: l’oggetto Gtk.ListBoxSortFunc,
ovvero la funzione di sort, oppure None;
user_data: i parametri da passare a sort_func;
L’oggetto Gtk.ListBoxSortFunc si aspetta in ingresso i seguenti parametri:
row1: la prima row (Gtk.ListBoxRow);
row2: la seconda row (Gtk.ListBoxRow);
user_data: un oggetto o None
Ritorna un numero < 0 se row1 deve stare prima di row2, un numero=0, se sono uguali e un numero > 0 se row1 deve stare dopo row2.

unselect_all()

Deseleziona tutti i children della listbox, se il selection-mode lo permette (MULTIPLE).

unselect_row(row)

Deseleziona la singola row, se il selection mode lo permette.
Parametri:
row: l’oggetto Gtk.ListBoxRow che vogliamo deselezionare

Di seguito un codice d’esempio:

import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, GObject


class ListBoxRowWithData(Gtk.ListBoxRow):
    def __init__(self, name, role):
        super(Gtk.ListBoxRow, self).__init__()
        self.name = name
        self.role = role
        label_name = Gtk.Label(label=self.name, xalign=0)
        label_role = Gtk.Label(label=self.role, xalign=1)
        hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=10)
        hbox.pack_start(label_name, True, True, 0)
        hbox.pack_start(label_role, True, True, 0)
        self.add(hbox)


class NamedSwitch(Gtk.Switch):
    __gproperties__ = {"name": (str,  # type
                                "switch name",  # nick
                                "the setting the switch enables",  # desc
                                "",  # default
                                GObject.ParamFlags.READWRITE, ),
                       }

    def __init__(self):
        super().__init__()

    def do_get_property(self, prop):
        print("INFO: getting property '%s'" % prop)
        return self.name

    def do_set_property(self, prop, value):
        print("INFO: setting property '%s' to %s" % (prop, value))
        self.name = value


class GWindow(Gtk.Window):
    def __init__(self):
        super().__init__(title="ListBox Demo")
        self.set_border_width(10)

        box_outer = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6)
        self.add(box_outer)

        listbox = Gtk.ListBox()
        listbox.set_selection_mode(Gtk.SelectionMode.NONE)
        box_outer.pack_start(listbox, True, True, 0)
        # build first row
        row1 = Gtk.ListBoxRow()
        hbox1 = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=50)
        mod_label = "Modificatore Difesa"
        label = Gtk.Label(label=mod_label, xalign=0)
        hbox1.pack_start(label, True, True, 0)
        switch1 = NamedSwitch()
        switch1.set_property("name", mod_label)
        switch1.props.valign = Gtk.Align.CENTER
        hbox1.pack_start(switch1, False, True, 0)
        row1.add(hbox1)
        listbox.add(row1)
        # build second row
        row2 = Gtk.ListBoxRow()
        hbox2 = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=50)
        trq_label = "Utilizzo Trequartista"
        label2 = Gtk.Label(label=trq_label, xalign=0)
        hbox2.pack_start(label2, True, True, 0)
        switch2 = NamedSwitch()
        switch2.set_property("name", trq_label)
        switch2.props.valign = Gtk.Align.CENTER
        hbox2.pack_start(switch2, False, True, 0)
        row2.add(hbox2)
        listbox.add(row2)
        # build third row
        row3 = Gtk.ListBoxRow()
        hbox3 = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=50)
        row3.add(hbox3)
        label = Gtk.Label(label="Modulo", xalign=0)
        combo = Gtk.ComboBoxText()
        for index, mod in enumerate(["343", "352", "442", "433"]):
            combo.insert(index, "%s" % index, mod)
        hbox3.pack_start(label, True, True, 0)
        hbox3.pack_start(combo, False, True, 0)
        listbox.add(row3)

        listbox2 = Gtk.ListBox()
        names = [('HANDANOVIC', 'Goalkeeper'), ('SKRINIAR', 'Defender'),
                   ('GODIN', 'Defender'), ('DE VRIJ', 'Defender'), ]
        for name, role in names:
            initial_role = ""
            item = ListBoxRowWithData(name, role)
            if role != initial_role:
                item.set_header(Gtk.Label(label="role"))
            listbox2.add(item)

        box_outer.pack_start(listbox2, True, True, 0)
        listbox2.show_all()

        # sorting
        listbox2.set_sort_func(self.sort_func)
        # binding
        listbox2.connect('row-activated', self.on_row_activated)
        switch1.connect("notify::active", self.on_switch_activated)
        switch2.connect("notify::active", self.on_switch_activated)

    @staticmethod
    def on_row_activated(listbox_widget, row):
        print("INFO: %s selezionato" % row.name)

    @staticmethod
    def sort_func(row_1, row_2, data=None):
        return row_1.name.lower() > row_2.name.lower()

    @staticmethod
    def on_switch_activated(switch, gparam):
        if switch.get_active():
            state = "ON"
        else:
            state = "OFF"
        print("INFO: '%s' %s" % (switch.get_property("name"), state))


if __name__ == "__main__":
    win = GWindow()
    win.connect("destroy", Gtk.main_quit)
    win.show_all()
    Gtk.main()

link di riferimento:

torna all’indice degli appunti
Gtk3 ListBox

Categorie:Gtk3, PyGObject, python Tag: , ,
I commenti sono chiusi.