PyGObject: Gtk.Notebook

13 Aprile 2020 Commenti chiusi

torna all’indice appunti

Notebook

Il widget Gtk.Notebook è un Gtk.Container i cui widget child sono pagine sulle
quali posso spostarmi agilmente semplicemente utilizzando i tab presenti sul proprio bordo.
E’ possibile scegliere su quale bordo posizionare i tabs utilizzando il metodo .set_tab_pos(),
qualora invece i tabs dovessere essere troppi, rispetto allo spazio disponibile, potremo
aggiungere le scrolling arrows, utilizzando il metodo set_scrollable().
Infine sarà possibile aggiungere dei popup menu con il metodo popup_enable().

Le properties ereditate da Gtk.Container sono:

Name Type Flags Short Description
enable-popup bool r/w/en Se True, premendo con il bottone destro del mouse
apparirà un popup menu che permetterà di scegliere la pagina su cui spostarsi
group-name str r/w/en Il nome del Group per il drag and drop dei tab
page int r/w/en l’indice della pagina corrente
scrollable bool r/w/en Se True, abilitiamo le scroll arrows da usare se ci sono troppe tabs
show-border bool r/w/en Se visualizzare il bordo
show-tabs bool r/w/en Se visualizzare i tabs
tab-pos Gtk.PositionType r/w/en Su quale bordo del notebook mettere i tabs

Le properties relative ai children sono:

Name Type Default Flags Short Description
detachable bool False r/w se il tab è “staccabile”
menu-label str None r/w la label visualizzata nel menu entry del child
position int 0 r/w L’indice del child nel notebook
reorderable bool False r/w Se il tab è is riordinabile
tab-expand bool False r/w Se espandere il tab del child
tab-fill bool True r/w Se il tab del child riempie lo spazio allocato
tab-label str None r/w La label visualizzata sul tab del child

Segnali

I principali segnali sono:

Name Short Description
create-window Il segnale “create-window” viene emesso quando un tab “detachable” viene rimosso dalla root window
page-added Il segnale “page-added” viene emesso nel notebook appena una pagina viene aggiunta al notebook
page-removed Il segnale “page-removed” viene emesso quando una pagina viene rimossa dal notebook
page-reordered Il segnale “page-reordered” viene emesso quando la pagine vengono riordinate
switch-page Emesso quando lo User o una funzione, cambia la pagina corrente

Metodi

Oltre ai soliti getter e setter relativi alle properties dell’oggetto Gtk.Notebook,
i principali metodi sono:

new()

Crea un nuovo widget Gtk.Notebook privo di pagine.

append_page(child, tab_label)

Aggiunge una pagina (append) al notebook e ritorna l’indice della pagina.
Se l’operazione fallisce, il metodo ritorna -1.

>>> import gi
... gi.require_version('Gtk', '3.0')
... from gi.repository import Gtk
>>> notebook = Gtk.Notebook.new()
>>> page_1 = Gtk.Label(label="First content")
>>> notebook.append_page(child=page_1, tab_label=Gtk.Label(label='First Page'))
0

Parametri:
child: il widget da utilizzare come contenuto della pagina;
tab_label: il widget da usare come label della pagina, o None
per usare la label di default “page N”;

append_page_menu(child, tab_label, menu_label)

Aggiunge una pagina (append) al notebook specificando il widget da usare come label nel popup
menu. Se l’operazione fallisce, il metodo ritorna -1.
Parametri:
child: il widget da utilizzare come contenuto della pagina;
tab_label: il widget da usare come label della pagina, o None
per usare la label di default “page N”;
menu_label: il widget da usare come label per il page-switch menu,
se questo è abilitato. Se menu_label=None e tab_label è un widget Gtk.Label (o None), allora la
label del menu sarà una nuova label creata con lo stesso testo di tab_label;
se invece tab_label non è una Gtk.Label, menu_label deve essere specificato in caso di utilizzo
del page-switch menu;

detach_tab(child)

Rimuove un child dal notebook.

>>> page_temp = Gtk.Label(label="Temp content")
>>> notebook.append_page(child=page_temp, tab_label=Gtk.Label(label='Temp Page'))
1
>>> notebook.get_children()
[<Gtk.Label object at 0x000000000583ae80 (GtkLabel at 0x0000000004d851f0)>, <Gtk.Label object at 0x0000000005815200 (GtkLabel at 0x0000000004d85530)>]
>>> notebook.detach_tab(page_temp)
>>> notebook.get_children()
[<Gtk.Label object at 0x000000000583ae80 (GtkLabel at 0x0000000004d851f0)>]

Parametri:
child: il widget che rappresenta il child da rimuovere.

get_action_widget(pack_type)

Ritorna l’action widget con il pack_type passato come argomento, o None se non è stato settato
alcun action widget. Vedere Gtk.Notebook.set_action_widget().
Parametri:
pack_type: il Gtk.PackType dell’action widget;
L’enum Gtk.PackType rappresenta il tipo di impacchettamento, che può essere: START (0) o END (1).

get_current_page()

Ritorna il numero della pagina corrente del Notebook. Se il notebook non ha ancora pagine, il
metodo ritornerà -1.

get_group_name()

Ritorna il nome del Group corrente.

get_menu_label(child)

Ritorna la label del menu se presente, o None se la pagina del notebook non ha label di menu che
non siano quelle di default (la label del Tab).

>>> notebook.get_menu_label(page_1)
>>> page_2 = Gtk.Label(label="Second content")
>>> notebook.append_page_menu(child=page_2, tab_label=Gtk.Label(label='Second Page'),
...                           menu_label=Gtk.Label(label='Second page menu label'))
1
>>> notebook.get_menu_label(page_2)
<Gtk.Label object at 0x000000000571bd40 (GtkLabel at 0x0000000004d85a10)>

Parametri:
child: il widget contenuto in una pagina del notebook;

get_menu_label_text(child)

Ritorna il testo della label del menu relativo alla pagina passata in argomento.

>>> notebook.get_menu_label_text(page_2)
'Second page menu label'

Parametri:
child: il widget contenuto in una pagina del notebook;

get_n_pages()

Ritorna il numero di pagine del notebook.

get_nth_page(page_num)

Ritorna il child widget della pagina con l’indice passato come argomento, o None.

>>> notebook.get_nth_page(0)
<Gtk.Label object at 0x000000000583ae80 (GtkLabel at 0x0000000004d851f0)>

Parametri:
page_num: l’indice della pagina nel notebook o -1 per ritornare
l’ultima pagina;

get_scrollable()

Ritorna True se sono presenti le scrollabe arrows nell’area dei tabs.
Vedere Gtk.Notebook.set_scrollable() per il settaggio.

get_show_border()

Ritorna True se viene disegnato il bordo del notebook.
Vedere Gtk.Notebook.set_show_border() per il settaggio.

get_show_tabs()

Ritorna True se vengono visualizzati i tabs.
Vedere Notebook.set_show_tabs() per il settaggio.

get_tab_detachable(child)

Ritorna True se il tab relativo al child passato in argomento, è “staccabile”.

Parametri:
child: il child widget di cui vogliamo la caratteristica del tab;

get_tab_label(child)

Ritorna il widget che fa da label al tab, del child passato come argomento.

>>> notebook.get_tab_label(page_1)
<Gtk.Label object at 0x0000000005815080 (GtkLabel at 0x0000000004d85390)>

Parametri:
child: la pagina della quale vogliamo il widget label del tab;

get_tab_label_text(child)

Ritorna il testo della label, del tab, del child passato come argomento.

>>> notebook.get_tab_label_text(page_1)
'First Page'

Parametri:
child: la pagina della quale vogliamo il testo della tab label;

get_tab_pos()

Ritorna il Gtk.PositionType che rappresenta il bordo sul quale appaiono i tabs.

>>> notebook.get_tab_pos()
<enum GTK_POS_TOP of type Gtk.PositionType>

get_tab_reorderable(child)

Ritorna True se il tab del child passato come argomento, può essere riordinato via drag and drop.

insert_page(child, tab_label, position)

Inserisce una pagina nel notebook, alla posizione specificata.
Parametri:
child: il widget usato come contenuto della pagina;
tab_label: il widget usato come label per la pagina, o None
per utilizzare la label di default “page N”;
position: l’indice (partendo da 0) al quale inserire la pagina.
Passando -1, la pagina verrà inserita alla fine (append);

insert_page_menu(child, tab_label, menu_label, position)

Inserisce una pagina alla posizione specificata, specificando anche il widget da usare come label
nel popup menu.
Parametri:
child: il widget usato come contenuto della pagina;
tab_label: il widget usato come label per la pagina, o None
per utilizzare la label di default “page N”;
menu_label: il widget da usare come label per il page-switch menu,
se questo è abilitato. Se menu_label=None e tab_label è un widget Gtk.Label (o None), allora la
label del menu sarà una nuova label creata con lo stesso testo di tab_label;
se invece tab_label non è una Gtk.Label, menu_label deve essere specificato in caso di utilizzo
del page-switch menu;
position: l’indice (partendo da 0) al quale inserire la pagina.
Passando -1, la pagina verrà inserita alla fine (append);

next_page()

Passa alla pagina successiva. Se siamo già all’ultima, non succede nulla.

page_num(child)

Ritorna l’indice della pagina che contiene il child passato come argomento.
Se il child non è nel notebook, il metodo ritorna -1.

Parametri:
child: il widget di cui vogliamo l’indice nel notebook;

popup_disable()

Disabilita il popup menu.

popup_enable()

Abilita il popup menu: se lo user clicca con il bottone destro sui tabs, apparirà un menu con
tutte le pagine del notebook.

prepend_page(child, tab_label)

Antepone una pagina al notebook.
Parametri:
child: il widget usato come contenuto della pagina;
tab_label: il widget usato come label per la pagina, o None
per utilizzare la label di default “page N”;

prepend_page_menu(child, tab_label, menu_label)

Antepone una pagina al notebook, specificando il widget da usare come label nel popup menu.
Parametri:
child: il widget usato come contenuto della pagina;
tab_label: il widget usato come label per la pagina, o None
per utilizzare la label di default “page N”;
menu_label: il widget da usare come label per il page-switch menu,
se questo è abilitato. Se menu_label=None e tab_label è un widget Gtk.Label (o None), allora la
label del menu sarà una nuova label creata con lo stesso testo di tab_label;
se invece tab_label non è una Gtk.Label, menu_label deve essere specificato in caso di utilizzo
del page-switch menu;

prev_page()

Passa alla pagina precedente. Se siamo nella prima pagina, non succede nulla.

remove_page(page_num)

Rimuove la pagina specificata dall’indice passato come argomento.
Parametri:
page_num: l’indice della pagina del notebook (partendo da 0) da
rimuovere. Se page_num = -1, verrà rimossa l’ultima pagina.

reorder_child(child, position)

Riordina la pagina contenente il child passato in argomento, cosicchè appaia nella posizione
specificata. Se position è maggiore o uguale al numero di children nella lista o -1, il child
specificato verrà spostato alla fine della lista.
Parametri:
child: il widget child da spostare;
position: la nuova positione in cui spostare il child, o -1
per spostare il child alla fine;

set_action_widget(widget, pack_type)

Setta il widget come appartenente al gruppo degli action widgets. A seconda del tipo di pack type,
il widget sarà posizionato prima o dopo i tabs. Nel caso si vogliano impacchettare più widget
dallo stesso lato, utilizzare un widget contenitore come Gtk.Box.
Notare che gli action widgets con child “interni” del notebook, quindi non sono inclusi nella
lista di children ritornata con il metodo Gtk.Container.foreach().
Parametri:
widget: un Gtk.Widget da settare come action widget;
pack_type: il tipo di Gtk.PackType dell’action widget;

set_current_page(page_num)

Passa alla pagina indicata dall’indice passato come argomento. Questa diventa la pagina corrente.
Parametri:
page_num: l’indice della pagina a cui passare (partendo da 0).
Se l’indice è -1, la pagina corrente diventerà l’ultima. Se l’indice è maggiore del numero di
pagine presenti nel notebook, non accadrà nulla.

set_group_name(group_name)

Setta un group name per il notebook. I Notebook con lo stesso group name potranno scambiarsi
i tabs tramite drag and drop.
Parametri:
group_name: il group name da associare al group;

set_menu_label(child, menu_label)

Setta il widget della label, del menu, della pagina contenente il child passato come argomento.
Parametri:
child: il widget usato come contenuto della pagina;
menu_label: il widget della label del menu, o None per il default;

set_menu_label_text(child, menu_text)

Setta il testo della label, del menu, della pagina contenente il child passato come argomento.
Parametri:
child: il widget usato come contenuto della pagina;
menu_text: il testo della label del menu;

set_scrollable(scrollable)

Setta la presenza o meno delle scrolling arrows, in caso ci siano più tabs dello spazio
disponibile nella tab area del notebook.
Parametri:
scrollable: il boolean che settato a True visualizza le scrollable
arrows;

set_show_border(show_border)

Settato a True visualizza il bordo attorno alle pagine del notebook.
Parametri:
show_border: il boolean che settato a True visualizza il bordo;

set_show_tabs(show_tabs)

Settato a True visualizza i tabs.
Parametri:
show_tabs: il boolean che settato a True visualizza i tabs;

set_tab_detachable(child, detachable)

Settato a True permette al tab di essere svincolato dal notebook per un altro notebook o widget.
Ovviamente perchè questo passaggio accada, i due notebooks devono condividere lo stesso name group
(vedi Gtk.Notebook.set_group_name()), così facendo i tabs potranno essere intercambiabili.
Se vogliamo che un widget interagisca con il notebook via Drag and Drop (ad esempio accetti i tabs
trascinati dal notebook stesso), dobbiamo settarlo come drop destination e accettare
il target “GTK_NOTEBOOK_TAB”. Così facendo il notebook salverà sulla selection
(Gtk.SelectionData) il child widget corrispondente al tab rimosso dal notebook.
Quando dovremo rimuovere il tab dal notebook (source), per completare l’operazione di drag and
drop sul widget (destination), dovremo utilizzare il metodo Gtk.Notebook.detach_tab().
Il drag and drop tra differenti notebook non è automatico, quindi dovremo codificarlo manualmente.
Parametri:
child: il widget che vogliamo rendere svincolabile;
detachable: il boolean che settato a True rende il tab detachable;

set_tab_label(child, tab_label)

Modifica il widget della label del tab, del child passato come argomento.
Se tab_label è None verrà utilizzata la label di default “page N”.
Parametri:
child: il widget usato per il contenuto della pagina;
tab_label: il widget della label del tab, o None per il default;

set_tab_label_text(child, tab_text)

Modifica il testo della label del tab, del child passato come argomento.
Parametri:
child: il widget usato per il contenuto della pagina;
tab_text: il testo della label;

set_tab_pos(pos)

Setta la posizione dove verranno visualizzati i tabs per spostarsi tra le pagine.
Parametri:
pos: l’enum Gtk.PositionType che indica il bordo dove verranno
visualizzati i tabs. I valori di Gtk.PositionType possono essere:
LEFT (0): i tabs vengono visualizzati sul bordo sinistro del notebook;
RIGHT (1): i tabs vengono visualizzati sul bordo destro del notebook;
TOP (2): i tabs vengono visualizzati nella parte superiore del notebook;
BOTTOM (3): i tabs vengono visualizzati nella parte inferiore del notebook;

set_tab_reorderable(child, reorderable)

Settato a True rende il tab del child passato come argomento, riordinabile tramite drag and drop.
Parametri:
child: il widget usato per il contenuto della pagina;
reorderable: il boolean che rende il tab riordinabile o meno;

Ecco un codice di esempio:

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


class GWindow(Gtk.Window):

    def __init__(self):
        super().__init__(title="Simple Notebook Example")
        self.set_border_width(3)
        self.set_default_size(200, 200)

        notebook = Gtk.Notebook.new()
        notebook.popup_enable()

        page_1 = Gtk.Box()
        page_1.set_border_width(10)
        page_1.add(Gtk.Label(label='Default Page!'))
        notebook.append_page_menu(child=page_1,
                                  tab_label=Gtk.Label(label='Plain Title'),
                                  menu_label=Gtk.Label(label='First Page'))
        page_2 = Gtk.Box()
        page_2.set_border_width(10)
        page_2.add(Gtk.Label(label='A page with an image for a Title.'))
        image = Gtk.Image.new_from_icon_name("go-next", Gtk.IconSize.MENU)
        notebook.append_page_menu(child=page_2, tab_label=image,
                                  menu_label=Gtk.Label(label='Second Page'))
        notebook.set_tab_reorderable(page_2, True)

        self.add(notebook)
        #bindings
        notebook.connect("switch-page", self.on_change_cur_page)

    def on_change_cur_page(self, notebook, page, page_num):
        print("INFO: current page is '%s'" % notebook.get_menu_label_text(page))


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 Notebook

Categorie:Gtk3, PyGObject, python Tag: , ,

PyGObject: Gtk.MessageDialog

13 Aprile 2020 Commenti chiusi

torna all’indice degli appunti

MessageDialog

Il widget Gtk.MessageDialog è un widget che visualizza una finestra di dialog con un testo e
all’occorrenza dei bottoni di scelta.
La differenza tra Gtk.MessageDialog e Gtk.Dialog è che nel primo, viene settata a True la property
“skip-taskbar-hint”, che permette di nascondere il dialog all task-bar.
Il metodo migliore per utilizzare un dialog, è chiamarne il metodo run() che rende il dialog
modal.
In sostanza modal significa che il dialog diventa automaticamente figlio della top-level window
principale dalla quale lo abbiamo generato e attende fino a che l’utente non interagisce con esso
(es. cliccando un Button), per poi tornare alla window parent che l’ha generato.

Per creare un message dialog si utilizza il costruttore Gtk.MessageDialog(*args, **kwargs).

Le properties principali dell’oggetto MessageDialog sono:

Name Type Flags Short Description
buttons Gtk.ButtonsType w/co I bottoni (Gtk.ButtonsType) visualizzati nel dialog
message-area Gtk.Widget r il widget Gtk.Box che gestisce le labels primaria e secondaria
message-type Gtk.MessageType r/w/c/en l’oggetto Gtk.MessageType che definisce il tipo di oggetto
secondary-text str r/w il messaggio secondario del dialog
secondary-use-markup bool r/w/en il boolean che, settato a True, permette di includere il Pango markup
text str r/w il testo principale del dialog
use-markup bool r/w/en il boolean che, settato a True, permette di includere il Pango markup
 
>>> import gi
>>> gi.require_version('Gtk', '3.0')
>>> from gi.repository import Gtk, GLib, Gdk
>>> dialog = Gtk.MessageDialog(parent=None, use_markup=False, message_type=Gtk.MessageType.INFO,
...                            buttons=Gtk.ButtonsType.OK, text="This is an INFO message dialog")

E’ possibile passare i parametri del widget in fase di costruzione, ma è possibile accedervi e
modificarli anche in seguito, utilizzando i metodi getter e setter get_property(property_name)
e set_property(property_name, property_value):
A differenza di altri widget, però, le properties leggibili, sono limitate, poichè i flags settati
per queste, non permettono la lettura/scrittura:

 
>>> for p in dialog.props:
...     if p.flags == 227:
...         print(p)        
...         
<GParamString 'name'>
<GParamObject 'parent'>
<GParamBoolean 'is-focus'>
<GParamString 'tooltip-markup'>
<GParamString 'tooltip-text'>
<GParamInt 'margin'>
<GParamBoolean 'expand'>
<GParamString 'title'>
<GParamString 'role'>
<GParamString 'text'>
<GParamString 'secondary-text'>
>>> dialog.get_property("text")
'This is an INFO message dialog'

oppure con i metodi getter e setter specifici get_() e set_(value):

 
>>> dialog.set_tooltip_text("Tooltip text")
>>> dialog.get_tooltip_text()
'Tooltip text'

Quindi è bene settare le properties non accessibili, in fase di costruzione!

Metodi

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

format_secondary_markup(message_format)

Setta il testo secondario del message dialog che verrà formattato con il Pango text markup language.
Questa funzione non esegue l’escape di caratteri XML speciali.
Parametri:
message_format: la stringa in formato markup;

format_secondary_text(message_format)

Setta il testo secondario del message dialog.
Parametri:
message_format: la stringa in formato markup;

get_message_area()

Ritorna un oggetto Gtk.Box corrispondente all’area dedicata dal message dialog, al testo

set_markup(str)

Setta il testo principale del message dialog che verrà formattato con il Pango text markup language.
Parametri:
str: la stringa in formato markup;

Tipi di MessageDialog

I tipi di MessageDialog sono definiti dall’Enum message_type che passiamo in fase di costruzione.
Questo Enum è di tipo Gtk.MessageType e può
assumere i seguenti valori:

INFO (0): Messaggio informativo semplice, di solito corredato da un Button OK.
WARNING (1): Messaggio di avviso;
QUESTION (2): Messaggio di scelta, con bottoni YES/NO;
ERROR (3): Messaggio di errore;
OTHER (4): Nessuna delle precedenti. E’ un messaggio personalizzabile;

Image

Settare un’immagine nel message dialog è molto semplice e ci sono più modi.
Creiamo un oggetto Gtk.Image con il classmethod Gtk.Image.new_from_file,
lo rendiamo visibile con il metodo show() e lo settiamo in fase di costruzione
dell’oggetto Gtk.MessageDialog con la property “image”.

Di seguito un codice d’esempio:

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


class GWindow(Gtk.Window):

    def __init__(self):
        super().__init__(title="MessageDialog Example")

        button1 = Gtk.Button(label="Information")
        button2 = Gtk.Button(label="Error")
        button3 = Gtk.Button(label="Warning")
        button4 = Gtk.Button(label="Question")
        # Bindings
        button1.connect("clicked", self.on_info_clicked)
        button2.connect("clicked", self.on_error_clicked)
        button4.connect("clicked", self.on_question_clicked)
        button3.connect("clicked", self.on_warning_clicked)
        # Layout
        box = Gtk.Box(spacing=6)
        box.add(button1)
        box.add(button2)
        box.add(button3)
        box.add(button4)
        self.add(box)

    def on_info_clicked(self, widget):
        image = Gtk.Image.new_from_file("info.png")
        image.show()
        dialog = Gtk.MessageDialog(parent=self, use_markup=False, title="Info",
                                   message_type=Gtk.MessageType.INFO,
                                   buttons=Gtk.ButtonsType.OK, image=image,
                                   text="Primary Message Text")
        dialog.format_secondary_text("secondary text that explains things")
        dialog.run()  # Return when user click dialog buttons
        dialog.destroy()

    def on_error_clicked(self, widget):
        image = Gtk.Image.new_from_file("error.png")
        image.show()
        dialog = Gtk.MessageDialog(parent=self, use_markup=True, title="Error",
                                   message_type=Gtk.MessageType.ERROR,
                                   buttons=Gtk.ButtonsType.CANCEL, image=image,
                                   text='<span foreground="red" weight="bold">'
                                        'Primary Error Message Text</span>')
        dialog.format_secondary_text("secondary text that explains things")
        dialog.run()
        dialog.destroy()

    def on_warning_clicked(self, widget):
        image = Gtk.Image.new_from_file("warning.png")
        image.show()
        dialog = Gtk.MessageDialog(parent=self, use_markup=True, 
                                   title="Warning", image=image,
                                   message_type=Gtk.MessageType.WARNING,
                                   buttons=Gtk.ButtonsType.OK_CANCEL, 
                                   text='<span foreground="blue" weight="bold">'
                                        'Primary Warning Message Text</span>')
        dialog.format_secondary_text("secondary text that explains things")
        response = dialog.run()
        if response == Gtk.ResponseType.OK:
            print("WARNING: dialog closed by clicking OK button")
        elif response == Gtk.ResponseType.CANCEL:
            print("WARNING: dialog closed by clicking CANCEL button")
        dialog.destroy()

    def on_question_clicked(self, widget):
        image = Gtk.Image.new_from_file("question.png")
        image.show()
        dialog = Gtk.MessageDialog(parent=self, use_markup=False,
                                   title="Question", 
                                   message_type=Gtk.MessageType.QUESTION,
                                   buttons=Gtk.ButtonsType.YES_NO,
                                   text="This is an QUESTION MessageDialog")
        dialog.format_secondary_text("secondary text that explains things")
        response = dialog.run()
        if response == Gtk.ResponseType.YES:
            print("INFO: dialog closed by clicking YES button")
        elif response == Gtk.ResponseType.NO:
            print("INFO: dialog closed by clicking NO button")
        dialog.destroy()


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

Custom Dialog

Se nessuno dei dialogs disponibili soddisfa le nostre esigenze, possiamo sempre crearne uno
personalizzato utilizzando la classe Gtk.Dialog.
Ad esempio vogliamo inserire all’interno una entry per digitare un valore e recuperarlo, vogliamo
mettere una o più labels e l’icona preferita…

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


class CustomDialog(Gtk.Dialog):
    def __init__(self, parent):
        super().__init__(title="Custom Dialog", parent=parent)
        self.result = None
        self.add_buttons(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
                         Gtk.STOCK_OK, Gtk.ResponseType.OK)
        self.set_default_size(250, 100)
        image = Gtk.Image.new_from_file("warning.png")
        image.show()
        label = Gtk.Label(label="Enter new value")
        self.entry = Gtk.Entry()
        box = self.get_content_area()
        box.set_spacing(15)
        box.add(image)
        box.add(label)
        box.add(self.entry)
        self.show_all()
        # bindings
        self.connect("response", self.on_response)  # get the entry value

    def on_response(self, widget, response_id):
        self.result = self.entry.get_text()

    def get_result(self):
        return self.result


class GWindow(Gtk.Window):
    def __init__(self):
        super().__init__(title="Custom Dialog Example")
        self.set_border_width(6)
        button = Gtk.Button(label="Open dialog")
        button.connect("clicked", self.on_button_clicked)
        self.add(button)

    def on_button_clicked(self, widget):
        dialog = CustomDialog(parent=self)
        response = dialog.run()
        if response == Gtk.ResponseType.OK:
            print("INFO: The OK button was clicked with result %s" %
                  dialog.get_result())
        elif response == Gtk.ResponseType.CANCEL:
            print("INFO: The Cancel button was clicked")
        dialog.destroy()


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

Nota:
connettere il dialog al segnale response, ci permettere di assegnare il valore della entry nella
nostra variabile, che poi possiamo recuperare all’occorrenza con il getter.

link di riferimento:

torna all’indice degli appunti
Gtk3 MessageDialog

Categorie:Gtk3, PyGObject, python Tag: , ,

PyGObject: Gtk.TextView

13 Aprile 2020 Commenti chiusi

torna all’indice appunti

HeadBar

Il Gtk.HeaderBar è simile ad un Gtk.Box orizzontale, permette infatti di posizionare children all’inizio o alla fine.
In aggiunta permette di avere un titolo da visualizzare, tale titolo sarà centrato sulla larghezza del box.
Dal momento che GTK+ supporta le decorazioni lato Client, un oggetto Gtk.HeaderBar può essere utilizzato
al posto della title bar (che è renderizzata dal Window Manager).
Una Gtk.HeaderBar dà anche l’accesso ai controlli della window, come il close button e i window menu.

Le properties principali sono:

Name Type Flags Short Description
custom-title Gtk.Widget r/w Il title widget personalizzato da visualizzare
decoration-layout str r/w il layout per le decorazioni della window
decoration-layout-set bool r/w Se la property “decoration-layout” è stata settata
has-subtitle bool r/w/en Se riserva spazio per un sottotitolo
show-close-button bool r/w/en Se deve visualizzare le decorazioni della window (es. close button)
spacing int r/w/en La quantità di spazio tra i children
subtitle str r/w Il sottotitolo da visualizzare
title str r/w Il titolo da visualizzare

Metodi

Oltre ai soliti getter e setter relativi alle properties dell’oggetto Gtk.HeaderBar, i principali metodi sono:

new()

Crea un nuovo widget Gtk.HeaderBar

get_custom_title()

Ritorna il title widget personalizzato dell’header, o None se non ne è stato settato nessuno esplicitamente.

get_decoration_layout()

Ritorna una stringa che rappresenta il decoration layout dell’header settato con il metodo Gtk.HeaderBar.set_decoration_layout().

get_has_subtitle()

Ritorna True se l’headerbar riserva spazio per un sottotitolo

get_show_close_button()

Ritorna True se nell’headerbar sono visualizzate le window decorations, ad esempio il window close button.

get_subtitle()

Ritorna il sottotitolo della headerbar, o None se non è stato settato alcun sottotitolo esplicitamente.

get_title()

Ritorna il titolo della headerbar, o None se non è stato settato alcun titolo esplicitamente.

pack_end(child)

Aggiunge un child alla headerbar partendo dalla fine (come per il Gtk.Box).
I parametri sono:
child: il widget child (Gtk.Widget) da aggiungere alla headerbar;

pack_start(child)
Aggiunge un child alla headerbar partendo dall’inizio (come per il Gtk.Box).
I parametri sono:
child: il widget child (Gtk.Widget) da aggiungere alla headerbar;

set_custom_title(title_widget)

Aggiunge un titolo personalizzato alla headerbar. Questo sostituisce l’eventuale titolo settato con il metodo Gtk.HeaderBar.set_title().
I parametri sono:
title_widget: il widget title (Gtk.Widget) da utilizzare come titolo;

set_decoration_layout(layout)

Setta il decoration layout per la headerbar, sovrascrivendo il Gtk.Setting “gtk-decoration-layout” (ad esempio non vogliamo buttons sulla destra).
Il formato della stringa è dato dai nomi dei buttons, separati da comma (virgola) e colon (due punti “:”) che separa ciò
che deve essere visualizzato a sinistra, da quello che deve essere visualizzato a destra.
Ad esempio “menu:minimize,maximize,close” significa che a sinistra avremo un menu, mentre a destra i buttons minimize, maximize
e close.
I parametri sono:
layout: la stringa che rappresenta il decoration layout, o None per togliere il layout;

set_has_subtitle(setting)

Serve per riservare o meno lo spazio nella headerbar, per un sottotitolo.
I parametri sono:
setting: True per riservare spazio al sottotitolo, altrimenti False;

set_show_close_button(setting)

Setta se questa headerbar debba visualizzare, o meno, le standard window decorations, che includono i buttons close, maximize e minimize.
I parametri sono:
setting: True per visualizzare le standard window decorations, altrimenti False;

set_subtitle(subtitle)

Setta il sottotitolo della Gtk.HeaderBar. Notare che la HeaderBar, di default, riserva un’area per il sottotitolo, anche se al metodo viene passato
None. Se non vogliamo un’area dedicata dobbiamo settare la property “has-subtitle” a False.
I parametri sono:
subtitle: la stringa che indica il sottotitolo da visualizzare, o None;

set_title(title)

Setta il titolo della Gtk.HeaderBar.
I parametri sono:
title: la stringa che indica il titolo da visualizzare, o None;

Di seguito un codice di esempio:

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


class SearchDialog(Gtk.Dialog):
    def __init__(self, parent):
        super().__init__("Search", parent)
        self.add_buttons(Gtk.STOCK_FIND, Gtk.ResponseType.OK,
                         Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL)
        box = self.get_content_area()
        box.add(Gtk.Label(label="Inserisci il testo da cercare"))
        self.entry = Gtk.Entry.new()
        box.add(self.entry)
        self.show_all()


class GWindow(Gtk.Window):
    def __init__(self):
        super().__init__(title="TextView Example")
        self.text_view = None
        self.text_buffer = None
        self.tag_bold = None
        self.tag_italic = None
        self.tag_underline = None
        self.tag_found = None
        self.grid = Gtk.Grid()

        self.set_default_size(500, 400)
        self.add(self.grid)
        self.create_textview()
        self.create_toolbar()
        self.create_buttons()

    def create_toolbar(self):
        toolbar = Gtk.Toolbar()
        self.grid.attach(toolbar, 0, 0, 3, 1)
        # Button Bold
        button_bold = Gtk.ToolButton()
        button_bold.set_icon_name("format-text-bold-symbolic")
        toolbar.insert(button_bold, 0)
        # Button Italic
        button_italic = Gtk.ToolButton()
        button_italic.set_icon_name("format-text-italic-symbolic")
        toolbar.insert(button_italic, 1)
        # Button underline
        button_underline = Gtk.ToolButton()
        button_underline.set_icon_name("format-text-underline-symbolic")
        toolbar.insert(button_underline, 2)

        toolbar.insert(Gtk.SeparatorToolItem(), 3)

        # RadioButton justify left
        radio_j_left = Gtk.RadioToolButton()
        radio_j_left.set_icon_name("format-justify-left-symbolic")
        toolbar.insert(radio_j_left, 4)
        # RadioButton justify center
        radio_j_center = Gtk.RadioToolButton.new_from_widget(radio_j_left)
        radio_j_center.set_icon_name("format-justify-center-symbolic")
        toolbar.insert(radio_j_center, 5)
        # RadioButton justify right
        radio_j_right = Gtk.RadioToolButton.new_from_widget(radio_j_left)
        radio_j_right.set_icon_name("format-justify-right-symbolic")
        toolbar.insert(radio_j_right, 6)
        # RadioButton justify fill
        radio_j_fill = Gtk.RadioToolButton.new_from_widget(radio_j_left)
        radio_j_fill.set_icon_name("format-justify-fill-symbolic")
        toolbar.insert(radio_j_fill, 7)

        toolbar.insert(Gtk.SeparatorToolItem(), 8)

        button_clear = Gtk.ToolButton()
        button_clear.set_icon_name("edit-clear-symbolic")
        toolbar.insert(button_clear, 9)

        toolbar.insert(Gtk.SeparatorToolItem(), 10)

        button_search = Gtk.ToolButton()
        button_search.set_icon_name("system-search-symbolic")
        toolbar.insert(button_search, 11)

        # Bindings
        # I Tags vengono creati nel metodo costruttore del textview
        button_bold.connect("clicked", self.on_button_clicked, self.tag_bold)
        button_italic.connect("clicked", self.on_button_clicked,
                              self.tag_italic)
        button_underline.connect("clicked", self.on_button_clicked,
                                 self.tag_underline)
        radio_j_left.connect("toggled", self.on_justify_toggled,
                             Gtk.Justification.LEFT)
        radio_j_center.connect("toggled", self.on_justify_toggled,
                               Gtk.Justification.CENTER)
        radio_j_right.connect("toggled", self.on_justify_toggled,
                              Gtk.Justification.RIGHT)
        radio_j_fill.connect("toggled", self.on_justify_toggled,
                             Gtk.Justification.FILL)
        button_clear.connect("clicked", self.on_clear_clicked)
        button_search.connect("clicked", self.on_search_clicked)

    def create_textview(self):
        scrolled_win = Gtk.ScrolledWindow()
        scrolled_win.set_hexpand(True)
        scrolled_win.set_vexpand(True)
        self.grid.attach(scrolled_win, 0, 1, 3, 1)
        # Text View
        self.text_view = Gtk.TextView()
        self.text_buffer = self.text_view.get_buffer()
        self.text_buffer.set_text("Lorem ipsum dolor sit amet, consectetur "
                                  "adipiscing elit, sed do eiusmod tempor "
                                  "incididunt ut labore et dolore magna aliqua."
                                  "Ut enim ad minim veniam, quis nostrud "
                                  "exercitation ullamco laboris (...)")
        scrolled_win.add(self.text_view)
        # Tags
        self.tag_bold = self.text_buffer.create_tag(tag_name="bold",
                                                    weight=Pango.Weight.BOLD)
        self.tag_italic = self.text_buffer.create_tag(tag_name="italic",
                                                      style=Pango.Style.ITALIC)
        self.tag_underline = self.text_buffer.create_tag(
            tag_name="underline", underline=Pango.Underline.SINGLE)
        self.tag_found = self.text_buffer.create_tag(tag_name="found",
                                                     background="yellow")

    def create_buttons(self):
        check_editable = Gtk.CheckButton(label="Editable")
        check_editable.set_active(True)
        self.grid.attach(check_editable, 0, 2, 1, 1)

        check_cursor = Gtk.CheckButton(label="Cursor Visible")
        check_cursor.set_active(True)
        self.grid.attach_next_to(check_cursor, check_editable,
                                 Gtk.PositionType.RIGHT, 1, 1)
        radio_wrapnone = Gtk.RadioButton.new_with_label_from_widget(
            None, "No Wrapping")
        self.grid.attach(radio_wrapnone, 0, 3, 1, 1)

        radio_wrapchar = Gtk.RadioButton.new_with_label_from_widget(
            radio_wrapnone, "Character Wrapping")
        self.grid.attach_next_to(radio_wrapchar, radio_wrapnone,
                                 Gtk.PositionType.RIGHT, 1, 1)

        radio_wrapword = Gtk.RadioButton.new_with_label_from_widget(
            radio_wrapnone, "Word Wrapping")
        self.grid.attach_next_to(radio_wrapword, radio_wrapchar,
                                 Gtk.PositionType.RIGHT, 1, 1)

        # Bindings
        radio_wrapnone.connect("toggled", self.on_wrap_toggled,
                               Gtk.WrapMode.NONE)
        radio_wrapchar.connect("toggled", self.on_wrap_toggled,
                               Gtk.WrapMode.CHAR)
        radio_wrapword.connect("toggled", self.on_wrap_toggled,
                               Gtk.WrapMode.WORD)
        check_editable.connect("toggled", self.on_editable_toggled)
        check_editable.connect("toggled", self.on_cursor_toggled)

    def on_button_clicked(self, widget, tag):
        bounds = self.text_buffer.get_selection_bounds()
        if len(bounds) != 0:
            start, end = bounds
            self.text_buffer.apply_tag(tag, start, end)

    def on_clear_clicked(self, widget):
        start = self.text_buffer.get_start_iter()
        end = self.text_buffer.get_end_iter()
        self.text_buffer.remove_all_tags(start, end)

    def on_editable_toggled(self, widget):
        self.text_view.set_editable(widget.get_active())

    def on_cursor_toggled(self, widget):
        self.text_view.set_cursor_visible(widget.get_active())

    def on_wrap_toggled(self, widget, mode):
        self.text_view.set_wrap_mode(mode)

    def on_justify_toggled(self, widget, justification):
        self.text_view.set_justification(justification)

    def on_search_clicked(self, widget):
        dialog = SearchDialog(parent=self)
        response = dialog.run()
        if response == Gtk.ResponseType.OK:
            cursor_mark = self.text_buffer.get_insert()
            start = self.text_buffer.get_iter_at_mark(cursor_mark)
            if start.get_offset() == self.text_buffer.get_char_count():
                start = self.text_buffer.get_start_iter()

            self.search_and_mark(dialog.entry.get_text(), start)

        dialog.destroy()

    def search_and_mark(self, text, start):
        end = self.text_buffer.get_end_iter()
        match = start.forward_search(text, 0, end)

        if match is not None:
            match_start, match_end = match
            self.text_buffer.apply_tag(self.tag_found, match_start, match_end)
            self.search_and_mark(text, match_end)


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 HeaderBar

Categorie:Gtk3, PyGObject, python Tag: , ,

PyGObject: Gtk.Toolbar

13 Aprile 2020 Commenti chiusi

torna all’indice appunti

ToolBar

Una toolbar può contenere istanze di sottoclassi di Gtk.ToolItem.
Per aggiungere un’istanza di Gtk.ToolItem
alla toolbar, si utilizza il metodo Gtk.Toolbar.insert().
Per rimuovere un elemento dalla toolbar si usa il metodo Gtk.Container.remove().
Per aggiungere un button alla toolbar, aggiungere un’istanza di Gtk.ToolButton.
Gli elementi della Toolbar possono essere raggruppati visivamente aggiungendo istanze di
Gtk.SeparatorToolItem alla toolbar.
Se la property “expand” del child della Gtk.Toolbar è True e la property “draw”
di Gtk.SeparatorToolItem è False, l’effetto è di forzare tutti gli elementi
seguenti, alla fine della toolbar.
Di default, una toolbar può essere ristretta (shrunk), in tal caso aggiungerà delle arrow button
per mostrare tutti i Gtk.ToolItem non visibili.
Per evitare questo comportamento e avere lo spazio necessario per tutti i children, chiamare il
metodo Gtk.Toolbar.set_show_arrow() per settare la property “show-arrow”
a False.
E’ possibile creare un menu contestuale per la toolbar, connettendo il segnale
“popup-context-menu” a Gtk.Toolbar.

Le properties principali sono:

Name Type Flags Short Description
icon-size Gtk.IconSize r/w/en La dimensione delle icone nella toolbar
icon-size-set bool r/w Se la property “icon-size” è stata settata
show-arrow bool r/w/en Se una freccia deve essere visualizzata quando la toolbar non può contenere tutti gli elementi
toolbar-style Gtk.ToolbarStyle r/w/en Lo stile con cui disegnare la toolbar
button-relief Gtk.ReliefStyle r Il tipo di bevel attorno ai buttons della toolbar
max-child-expand int r Il massimo spazio che un elemento espandibile si prenderà

Metodi

Oltre ai soliti getter e setter relativi alle properties dell’oggetto Gtk.ToolBar,
i principali metodi sono:

new()

Metodo costruttore che crea una nuova ToolBar.

get_drop_index(x, y)

Ritorna la posizione sulla toolbar, corrispondente al punto indicato.
Utile quando trasciniamo elementi sulla toolbar:
Parametri:
x: la coordinata x di un punto sulla toolbar;
y: la coordinata y di un punto sulla toolbar;

get_icon_size()

Ritorna l’oggetto Gtk.IconSize che rappresenta la dimensione dell’icona sulla toolbar

get_item_index(item)

Ritorna l’indice della posizione dell’elemento sulla toolbar.
Parametri:
item: l’elemento (Gtk.ToolItem) del quale vogliamo conoscere
l’indice della posizione;

get_n_items()

Ritorna il numero degli elementi della toolbar.

get_nth_item(n)

Ritorna l “n”esimo elemento sulla toolbar.
Parametri:
n: l’indice della posizione sulla toolbar;

get_relief_style()

Ritorna il tipo di rilievo (Gtk.ReliefStyle) dei bottoni nella toolbar, settati con il metodo
Gtk.Button.set_relief(). L’enum Gtk.ReliefStyle può assumere i seguenti valori:
NORMAL (0): disegna un “relief” normale;
NONE (2): nessun rilievo;

get_show_arrow()

Ritorna True se la ToolBar mostra le frecce in caso di bottoni eccedenti
rispetto allo spazio deisponibile.

get_style()

Ritorna lo style corrente della ToolBar. L’enum Gtk.ToolbarStyle indica se la toolbar debba
visualizzare sono i testi, le icone, o entrambi.
I valori possibili sono i seguenti:
ICONS (0): i bottoni nella toolbar visualizzano solo le icone;
TEXT (1): i bottoni nella toolbar visualizzano solo i testi (labels);
BOTH (2): i bottoni nella toolbar visualizzano testi e icone;
BOTH_HORIZ (3): i bottoni nella toolbar visualizzano testi e icone gli accanto alle altre, invece
che gli uni sopra le altre (default);

insert(item, pos)

Inserisce un Gtk.ToolItem alla posizione data. Se la posizione è 0, il toolitem
viene inserito all’inizio della toolbar,
se la posizione è negativa, il tooitem viene inserito alla fine della toolbar.
Parametri:
item: l’oggetto Gtk.ToolItem da inserire nella toolbar;
pos: la posizione dove inserire il toolitem;

set_drop_highlight_item(tool_item, index_)

Evidenzia la toolbar per dare l’idea di come diventerebbe se l’elemento venisse aggiunto alla
toolbar alla posizione indicata.
Se l’elemento (tool_item) è None, l’evidenziazione viene spenta, così come viene
ignorata la posizione di inserimento (index_).
L’elemento tool_item passato al metodo non deve far parte di nessuna gerarchia di nessun widget e
allo stesso modo, quando un elemento viene settato come drop highlight item,
non può essere aggiunto a nessuna gerarchia di nessun widget e nemmeno usato come highlight item
di un’altra toolbar.
Parametri:
tool_item: l’oggetto Gtk.ToolItem da settare drop highlight item,
o None per spegnere l’highlighting;
index: la posizione del toolitem;

set_icon_size(icon_size)

Setta la dimensione delle stock icons nella toolbar. Possiamo chiamare il metodo, sia prima di
aggiungere le icone, sia dopo. Settando la dimensione con questo metodo, sovrascriverà l’eventuale
default icon size definita dall’utente.
Parametri:
icon_size: il size (Gtk.IconSize) che vogliamo per le stock icons
nella toolbar;

set_show_arrow(show_arrow)

Setta se la toolbar debba avere o meno le frecce indicanti bottoni eccedenti che la toolbar non
può mostrare. Se True, gli elementi che non stanno nella toolbar per motivi di
spazio e che hanno un elemento proxy menu, settato con il metodo
Gtk.ToolItem.set_proxy_menu_item(), saranno appunto disponibili in un
overflow menu, che può essere aperto grazie ad una freccia (arrow button).
Se False, la toolbar richiederà lo spazio necessario per mostrare tutti i suoi elementi.
Parametri:
show_arrow: il boolean che settato a True mostra un
overflow menu;

set_style(style)

Setta lo stile della toolbar. L’enum che ne decreta l’aspetto può assumere i seguenti valori:
ICONS (0): i bottoni nella toolbar visualizzano solo le icone;
TEXT (1): i bottoni nella toolbar visualizzano solo i testi (labels);
BOTH (2): i bottoni nella toolbar visualizzano testi e icone;
BOTH_HORIZ (3): i bottoni nella toolbar visualizzano testi e icone gli accanto alle altre, invece
che gli uni sopra le altre (default);
Parametri:
style: l’enum (Gtk.ToolbarStyle) che indica lo stile della toolbar;

unset_icon_size()

Elimina il settaggio delle dimensioni delle icone effettuato con Gtk.Toolbar.set_icon_size(),
così facendo verranno usate le user preferences, che altrimenti sarebbero sovrascritte dal metodo
precedente.

unset_style()

Elimina il settaggio della toolbar effettuato con Gtk.Toolbar.set_style(),
così facendo verranno usate le user preferences, che altrimenti sarebbero sovrascritte dal metodo
precedente.

Gtk.ToolButton

Come accennato prima, per la toolbar al posto del generico toolitem, è conveniente utilizzare
oggetti Gtk.ToolButton.
L’iter è molto semplice: si costruisce l’oggetto tool_bar, si istanziano gli oggetti toolbuttons e
si sceglie per essi, un’icona tra le stock icons
disponibili, si aggiungono i toolbuttons alla toolbar, si eseguono i bindings dei toolbuttons al
segnale “clicked”.

Ecco un codeice di esempio:

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


class AppWindow(Gtk.ApplicationWindow):
    def __init__(self):
        super().__init__(title="Toolbar Example")
        self.set_default_size(250, 100)

        tool_bar = Gtk.Toolbar.new()
        button_open = Gtk.ToolButton(stock_id=Gtk.STOCK_OPEN, label="Open")
        button_new = Gtk.ToolButton(stock_id=Gtk.STOCK_NEW, label="New")
        tool_bar.insert(item=button_new, pos=0)
        tool_bar.insert(item=button_open, pos=1)
        tool_bar.set_style(Gtk.ToolbarStyle.BOTH)

        box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
        box.pack_start(tool_bar, False, False, 0)
        self.add(box)

        # bindings
        button_new.connect('clicked', self.on_menu)
        button_open.connect('clicked', self.on_menu)
        self.connect('destroy', Gtk.main_quit)

    def on_menu(self, tool_button):
        print("INFO: menu '%s' clicked!" % tool_button.get_label())


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

Gtk.Builder e XML

Come già visto per la MenuBar, possiamo ottenere lo stesso risultato utilizzando Gtk.Builder.
Gtk.Builder è un oggetto che legge le descrizioni di una UI da un testo e ne
istanzia gli oggetti descritti in esso.
A grandi linee, all’interno del testo, gli oggetti del menu saranno così identificati:
UI ovvero l’interfaccia utente del menu: sarà compresa tra i tag

<interface></interface>

menu_model ovvero l’oggetto menu genitore: sarà compreso tra i tag

<menu></menu>

sub_menu ovvero le voci dei menu: saranno comprese tra i tag

<submenu></submenu>

item ovvero gli elementi interni alle voci di menu: saranno compresi tra i tag

<item></item>

attribute ovvero l’attributo dell’istanza che verrà creata dal buider: sarà
compreso tra i tag

<attribute></attribute>

Come nella MenuBar e a differenza dell’esempio precedente, qui entrano in gioco le actions.
Nel nostro caso precedente il testo che rappresenta il menu della app, sarà:

<?xml version="1.0" encoding="UTF-8"?>
<interface>
  <!-- interface-requires gtk+ 3.0 -->
  <object class="GtkToolbar" id="toolbar">
    <property name="visible">True</property>
    <property name="can_focus">False</property>
    <property name="hexpand">True</property>
    <property name="show_arrow">False</property>
    <child>
      <object class="GtkToolButton" id="new_button">
        <property name="use_action_appearance">False</property>
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <property name="use_action_appearance">False</property>
        <property name="is_important">True</property>
        <property name="action_name">win.new</property>
        <property name="label" translatable="yes">New</property>
        <property name="use_underline">True</property>
        <property name="stock_id">gtk-new</property>
      </object>
      <packing>
        <property name="expand">False</property>
        <property name="homogeneous">True</property>
      </packing>
    </child>
    <child>
      <object class="GtkToolButton" id="open_button">
        <property name="use_action_appearance">False</property>
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <property name="use_action_appearance">False</property>
        <property name="is_important">True</property>
        <property name="action_name">win.open</property>
        <property name="label" translatable="yes">Open</property>
        <property name="use_underline">True</property>
        <property name="stock_id">gtk-open</property>
      </object>
      <packing>
        <property name="expand">False</property>
        <property name="homogeneous">True</property>
      </packing>
    </child>
  </object>
</interface>

Basterà quindi creare il builder con il class_method Gtk.Builder.new_from_string(string, length).
Sarà quindi il builder stesso ad istanziare gli oggetti descritti nella stringa XML e a
recuperarli con il metodo get_object(string).
Rispetto a prima bisognerà creare le actions che si occuperanno di connettere gli elementi della
toolbar al segnale “activate”.

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


TOOLBAR_INFO = """
<?xml version="1.0" encoding="UTF-8"?>
<interface>
  <!-- interface-requires gtk+ 3.0 -->
  <object class="GtkToolbar" id="toolbar">
    <property name="visible">True</property>
    <property name="can_focus">False</property>
    <property name="hexpand">True</property>
    <property name="show_arrow">False</property>
    <child>
      <object class="GtkToolButton" id="new_button">
        <property name="use_action_appearance">False</property>
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <property name="use_action_appearance">False</property>
        <property name="is_important">True</property>
        <property name="action_name">win.new</property>
        <property name="label" translatable="yes">New</property>
        <property name="use_underline">True</property>
        <property name="stock_id">gtk-new</property>
      </object>
      <packing>
        <property name="expand">False</property>
        <property name="homogeneous">True</property>
      </packing>
    </child>
    <child>
      <object class="GtkToolButton" id="open_button">
        <property name="use_action_appearance">False</property>
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <property name="use_action_appearance">False</property>
        <property name="is_important">True</property>
        <property name="action_name">win.open</property>
        <property name="label" translatable="yes">Open</property>
        <property name="use_underline">True</property>
        <property name="stock_id">gtk-open</property>
      </object>
      <packing>
        <property name="expand">False</property>
        <property name="homogeneous">True</property>
      </packing>
    </child>
  </object>
</interface>
"""


class AppWindow(Gtk.ApplicationWindow):
    def __init__(self):
        super().__init__(title="Toolbar Example")
        self.set_default_size(250, 100)

        builder = Gtk.Builder.new_from_string(TOOLBAR_INFO, -1)

        act_new = Gio.SimpleAction.new(name='new', parameter_type=None)
        act_open = Gio.SimpleAction.new(name='open', parameter_type=None)
        self.add_action(act_new)
        self.add_action(act_open)

        tool_bar = builder.get_object('toolbar')
        tool_bar.set_style(Gtk.ToolbarStyle.BOTH)
        box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
        box.pack_start(tool_bar, False, False, 0)
        self.add(box)

        # bindings
        act_new.connect('activate', self.on_menu)
        act_open.connect('activate', self.on_menu)
        self.connect('destroy', Gtk.main_quit)

    def on_menu(self, action, value):
        print("INFO: menu '%s'" % action.props.name)


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

link di riferimento:

torna all’indice degli appunti
Gtk3 Toolbar
Gnome Stock icons

Categorie:Gtk3, PyGObject, python Tag: , ,

PyGObject: Gtk.ComboBox

13 Aprile 2020 Commenti chiusi

torna all’indice degli appunti

ComboBox

Il widget Gtk.ComboBox permette di selezionare un elemento da una lista.
Una volta selezionato l’elemento, il combobox lo visualizzerà.
Il combobox usa un pattern model-view e la lista degli elementi viene specificata
secondo il modello ad albero (tree-model).
Ci sono due modelli di dati da utilizzare:
il Gtk.ListStore e il Gtk.TreeStore.
Il Gtk.ListStore contiene semplici righe di dati (row), senza children,
mentre il Gtk.TreeStore può contenere dati con children.
La visualizzazione di tali elementi, si adatta al tipo di dato contenuto nel model grazie ai cell-renderers.
Questo è reso possibile dal fatto che Gtk.ComboBox implementa un’interfaccia
Gtk.CellLayout.
Di solito una combobox forza l’utente a scegliere tra gli elementi che dispone, ma dà la
possibilità di aggiungere una scelta, qualora questa non fosse presente, mettendo a disposizione
una Gtk.Entry. Quando la lista di elementi del combobox, riguarda semplici
testi, può essere conveniente utilizzare al posto del widget Gtk.ComboBox, un widget
Gtk.ComboBoxText.

Per creare una ComboBox si utilizza il costruttore Gtk.ComboBox(**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):

Le properties principali di una combobox sono le seguenti:

Name Type Flags Short Description
active int r/w/en l’item attivo al momento
active-id str r/w/en il valore dell’id di colonna per la riga attiva
button-sensitivity Gtk.SensitivityType r/w/en Se il dropdown button è sensibile quando il modulo è vuoto
cell-area Gtk.CellArea r/w/co il Gtk.CellArea usato per il layout delle celle
column-span-column int r/w/en la colonna del TreeModel che contiene i valori del column span
entry-text-column int r/w/en la colonna nel model del combobox da associare con le stringhe dalla entry
se il combobox è stato crato con la property “has-entry”=True
has-entry bool r/w/co se il combobox ha una entry
has-frame bool r/w/en se il combobox disegna un frame intorno al child
id-column int r/w/en La colonna nel model del combobox che fornisce gli ID per i valori nel model
model Gtk.TreeModelv r/w/en Il model per il combobox
popup-fixed-width bool r/w/en Se la larghezza del popup debba essere fissa rispetto alla larghezza allocata dal combobox
popup-shown bool r Se il dropdown del combobox viene visualizzato
row-span-column int r/w/en la colonna del TreeModel contenente i valori del row span
wrap-width int r/w/en La larghezza di Wrap per la collocazione degli elementi in una griglia
selection-mode Gtk.SelectionMode r/w/en il tipo di selection mode

La property selection-mode è 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
>>> ComboBox = Gtk.ComboBox()
>>> ComboBox.set_property("selection-mode", Gtk.SelectionMode.NONE)
>>> ComboBox.get_property("selection-mode")
<enum GTK_SELECTION_NONE of type Gtk.SelectionMode>

Come per gli altri widgets esistono i metodi getter e setter specifici get_*property_name*()
e set_*property_name*(value):

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 del combobox 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 del combobox, (selection-mode=MULTIPLE).

Metodi

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

new()

Metodo costruttore che crea un nuovo Gtk.ComboBox.

new_with_area(area)

Metodo costruttore che crea un Gtk.ComboBox vuoto usando l’area per disporre le celle.
Parametri:
area: la Gtk.CellArea usata per disporre i cell renderers;

new_with_area_and_entry(area)

Metodo costruttore che crea un Gtk.ComboBox vuoto usando l’area per disporre le celle, con una
entry.
Parametri:
area: la Gtk.CellArea usata per disporre i cell renderers;

new_with_entry()

Metodo costruttore che crea un Gtk.ComboBox vuoto con una entry.

new_with_model(model)

Metodo costruttore che crea un Gtk.ComboBox con un model inizializzato al model specificato.
Parametri:
model: un Gtk.TreeModel da associare al combobox;

new_with_model_and_entry(model)

Metodo costruttore che crea un Gtk.ComboBox con un model inizializzato al model specificato e una
entry.
Parametri:
model: un Gtk.TreeModel da associare al combobox;

get_active()

Ritorna l’indice dell’elemento attivo, o -1 se non ci sono elementi attivi.
Se il model è un treemodel non-flat e l’elemento attivo non è un child immediato della root del
tree, questo metodo ritorna gtk_tree_path_get_indices (path)[0], dove “path” è il Gtk.TreePath
dell’elemento attivo.

get_active_id()

Ritorna l’ID della row attiva del combobox. Questo valore viene preso dalla row attiva e dalla
colonna specificata dalla property “id-column” (vedere Gtk.ComboBox.set_id_column()).
Se la property “id-column” non è settata, o se non c’è una row attiva, o se la row attiva ha
ID=None, il metodo ritorna None.

get_active_iter()

Ritorna l’iter per l’elemento attivo, se esiste.

get_button_sensitivity()

Ritorna True se il combobox ha i dropdown button sensibili anche in caso di model senza elementi.

get_column_span_column()

Ritorna l’indice della colonna con l’informazione “column span” relativa al combobox.

get_entry_text_column()

Ritorna l’indice della colonna che il combobox sta usando per gestire le stringhe di testo
inserite nella entry del combobox stesso.

get_has_entry()

Ritorna True se il combobox ha una entry, altrimenti False.

get_id_column()

Ritorna l’indice della colonna che il combobox sta usando per gestire gli IDs.

get_model()

Ritorna il Gtk.TreeModel che sta funzionando come sorgente dati per il combobox.

get_popup_fixed_width()

Ritorna True se il popup usa una larghezza fissa.

get_row_span_column()

Ritorna l’id della colonna con l’informazione relativa al “row span” del combobox.

get_wrap_width()

Ritorna la larghezza di wrap usata per determinare il numero di colonne per il popup menu.
Se il “wrap width” è > 1, il combobox è in table mode.

popdown()

Nasconde il menu o la dropdown list del combobox.

popup()

Visualizza il menu o la dropdown list del combobox.

popup_for_device(device)

Fa apparire il menu o la dropdown list per il device specificato; la popup window sarà “afferrata”
e solo il device ed i suoi pointer/keyboard associati saranno gli unici Gdk.Devices abilitati a
spedire eventi ad essa.
Parametri:
device: il Gdk.Device sul quale far apparire menu o dropdown list

set_active(index)

Setta come attivo l’elemento con l’indice specificato.
Parametri:
index: un indice del model corrispondente all’elemento che
vogliamo rendere attivo, o -1 per non avere elementi attivi;

set_active_id(active_id)

Cambia la row attiva del combobox con quella della stringa ID uguale ad “active_id”, o,
se active_id=None, disattiva la row corrente.
Le Rows che hanno la stringa ID=None non possono essere rese attive da questo metodo.
Se la property “id-column” del combobox non è settata, o se nessuna row ha l’ID specificato,
allora il metodo non fa nulla e ritorna False. Ritorna True, invece in caso di successo.
Parametri:
active_id: la stringa cheindica l’ID della row da selezionare, o None;

set_active_iter(iter)

Setta l’elemento che ha l’iter specificato com attivo. Se iter=None viene disattivato l’elemento
attivo corrente.
Parametri:
iter: il Gtk.TreeIter o None;

set_button_sensitivity(sensitivity)

Setta il tipo di sensitività del dropdown button del combobox secondo il valore specificato.
sensitivity (enum Gtk.SensitivityType) può assumere i seguenti valori:
AUTO (0): la freccia (dropdown button) diventa “insensitive” quando si giunge alla fine;
ON (1): la freccia (dropdown button) è sempre “sensitive”;
OFF (2): la freccia (dropdown button) è sempre “insensitive”;
Parametri:
sensitivity: l’enum Gtk.SensitivityType che specifica la
sensitività del dropdown button (freccia);

set_column_span_column(column_span)

Setta la colonna con l’informazione “column span”. La colonna “column span” contiene quindi un
intero che indica su quante colonne verrà disposto un elemento.
Parametri:
column_span: l’indice della colonna nella quale inseriremo
l’informazione “column span”;

set_entry_text_column(text_column)

Setta la colonna del model che gestisce le stringhe della text_column (entry).
La colonna text_column nel model del combobox deve essere di tipo GObject.TYPE_STRING.
Ha rilevanza solo se il combobox è stato creato con la property “has-entry”=True.
Parametri:
text_column: l’indice della colonna nel model che gestirà i testi
della entry;

set_id_column(id_column)

Setta la colonna del model da usare per gestire le string IDs.
La colonna id_column nel model deve essere di tipo GObject.TYPE_STRING.
Parametri:
id_column: l’indice della colonna nel model che gestisce
le string IDs;

set_model(model)

Setta il model usato dal combobox. Verrà eliminato il model precedente.
Se model=None, non ci sarà nessun model settato per il combobox.
Questo metodo non azzera i cell renderers, quindi in caso si vogliano settare dei nuovi
cellrenderers per il nuovo model, bisognerà chiamare il metodo Gtk.CellLayout.clear().
Parametri:
model: il Gtk.TreeModel o None;

set_popup_fixed_width(fixed)

Specifica se la larghezza del popup debba essere una larghezza fissa.
Parametri:
fixed: se usare un popup a larghezza fissa;

set_row_separator_func(func, *data)

Setta la funzione di row separator, che è usata per determinare se una row debba essere disegnata
come separator. Se la funzione “row separator” è None, nessun separators verrà visualizzato
(comportamento di default).
Parametri:
func: la funzione Gtk.TreeViewRowSeparatorFunc;
data: i dati da passare alla funzione o None;

set_row_span_column(row_span)

Setta la colonna con l’informazione “row span”. La colonna “row span” contiene quindi un
intero che indica su quante righe verrà disposto un elemento.
Parametri:
row_span: l’indice della colonna nella quale inseriremo
l’informazione “row span”;

set_wrap_width(width)

Setta la larghezza di wrap del combobox. Il wrap è in sostanza il numero di colonne su cui
vogliamo venga disposto il popup, in una tabella
Parametri:
width: il numero di colonne per il wrap;

Di seguito un codice d’esempio:

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


class ComboBoxRowWithData(Gtk.ComboBoxRow):
    def __init__(self, name, role):
        super(Gtk.ComboBoxRow, 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="ComboBox Demo")
        self.set_border_width(10)

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

        ComboBox = Gtk.ComboBox()
        ComboBox.set_selection_mode(Gtk.SelectionMode.NONE)
        box_outer.pack_start(ComboBox, True, True, 0)
        # build first row
        row1 = Gtk.ComboBoxRow()
        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)
        ComboBox.add(row1)
        # build second row
        row2 = Gtk.ComboBoxRow()
        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)
        ComboBox.add(row2)
        # build third row
        row3 = Gtk.ComboBoxRow()
        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)
        ComboBox.add(row3)

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

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

        # sorting
        ComboBox2.set_sort_func(self.sort_func)
        # binding
        ComboBox2.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(ComboBox_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 ComboBox

Categorie:Gtk3, PyGObject, python Tag: , ,

PyGobject: Gtk.Button

13 Aprile 2020 Commenti chiusi

torna all’indice appunti

Button

Il widget Gtk.Button viene generalmente collegato ad una callback che viene invocata quando lo
stesso widget viene premuto.
Come accade per altri widget, il Gtk.Button può contenere altri widget (child), come ad esempio
Testi (Label) o immagini.

Per creare un Button si utilizza il costruttore Gtk.Button(*args, **kwargs),
dove gli argomenti più significativi sono “label” e “image”.
label: è una stringa di testo visualizzata nel Button
image: un oggetto Gtk.Image che rappresenta l’immagine sul Button.

 
>>> button = Gtk.Button()
>>> button
<Gtk.Button object at 0xb4a36edc (GtkButton at 0x88e3330)>

E’ possibile passare i parametri del widget in fase di costruzione, ma è possibile accedervi e
modificarli anche in seguito, utilizzando i metodi getter e setter get_property(property_name)
e set_property(property_name, property_value):

 
>>> button.get_property("label")
>>> button.set_property("label", "Click")
>>> button.get_property("label")
'Click'

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

 
>>> button.set_label("OK")
>>> button.get_label()
'OK'

Per creare un Button, esiste un metodo “scorciatoia”, new_with_label(label):

 
button1 = Gtk.Button.new_with_label("Click")

Le properties principali di un Gtk.Button sono:

Image

Per inserire un’immagine all’interno del widget, creiamo prima un oggetto Gtk.Image e lo settiamo
nel widget che lo conterrà:

 
>>> btn_ok = Gtk.Button(label="Click")
>>> image = Gtk.Image.new_from_file("OK24.png")
>>> btn_ok.set_image(image)
>>> btn_ok.get_image()
<Gtk.Image object at 0xb4a36dec (GtkImage at 0x88ea460)>

Segnali

Per connettere un widget ad una callback, in modo che, quando viene emesso un segnale specifico,
quest’ultima venga invocata, si utilizza il metodo connect(signal, callback):

 
>>> def on_click(button):
...     print("Button '%s' was clicked!" % button.get_label())
...     
>>> btn_ok.connect("clicked", on_click)
104
>>> btn_ok.clicked()
Button <Click> was clicked!

Come si nota, con il metodo clicked() abbiamo emesso il segnale “clicked” e la
callback è stata invocata. Questo corrisponde alla pressione del Button.
L’Integer ritornato dal metodo coonect(), invece, è l’ID-Handler che gestisce appunto la connessione
segnale-callback.
Con lo stesso ID, sarà infatti possibile disconnettere la callback dal segnale:

 
>>> btn_ok.disconnect(104)
>>> btn_ok.clicked()

Metodi

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

clicked()

emette un segnale di tipo “clicked”.

get_alignment()

ritorna l’allineamento orizzontale (xalign) e quello verticale (yalign) del widget;
“xalign” può assumere i valori: 0.0 per allineamento a sinistra, 1.0 per allineamento a destra;
“yalign” può assumere i valori: 0.0 per allineamento in alto, 1.0 per allineamento in basso;
0.5 ovviamente sta per centrato, sia orizzontalmente che verticalmente.

>>> btn_ok.get_alignment()
(xalign=0.5, yalign=0.5)

get_focus_on_click()

ritorna True se il Button dopo il click, trattiene il focus.

get_image()

ritorna l’oggetto Image utilizzato nel Button o None se assente;

get_image_position()

ritorna la posizione dell’immagine all’interno del widget.

>>> btn_ok.get_image_position()
<enum GTK_POS_LEFT of type Gtk.PositionType>

get_label()

ritorna il testo associato al Button.

get_relief()

ritorna lo stile “relief” settato per il Button.

get_use_underline()

ritorna True se viene utilizzato il mnemonic underline (accelerator key).

new()

E’ un metodo costruttore, crea un nuovo Gtk.Button.
In seguito possono essere settati i parametri (es. la Label), con i setter dedicati.

set_alignment(xalign, yalign)

setta l’allineamento del child. I valori di allineamento sono:
0.0 per allineamento a sinistra, 1.0 per allineamento a destra, 0.0 per allineamento in alto, 1.0
per allineamento in basso. Per l’allineamento centrato, si utilizza ovviamente 0.5.
I parametri sono:
xalign: il valore di allineamento orizzontale;
yalign: il valore di allineamento verticale;

set_always_show_image(always_show)

Settato a True, il Button visualizzerà sempre l’immagine (se disponibile), sovrascrivendo nel caso,
il Gtk.Settings “gtk-button-images”.
I parametri sono:
always_show: il boolean che a True visualizza sempre l’immagine;

set_image(image)

setta l’immagine nel Button.
I parametri sono:
image: il widget da settare come immagine;

set_image_position(position)

setta la posizione dell’immagine, rispetto al testo del Button.
Position è un enum di tipo Gtk.PositionType e può assumere i seguenti valori;
LEFT (0): immagine a sinistra rispetto al testo;
RIGHT (1): immagine a destra ridpetto al testo;
TOP (2): immagine sopra e testo sotto;
BOTTOM (3): immagine sotto e testo sopra:

>>> btn_ok.set_image_position(Gtk.PositionType(1))
>>> btn_ok.get_image_position()
<enum GTK_POS_RIGHT of type Gtk.PositionType>

I parametri sono:
position: l’enum Gtk.PositionType della posizione dell’immagine
rispetto al testo del Button;

set_relief(relief)

setta il “relief” style del Button. Il relief style può assumere i seguenti valori:
Gtk.ReliefStyle.NORMAL e Gtk.ReliefStyle.NONE.
I parametri sono:
relief: enum Gtk.ReliefStyle che indica il relief style del button;

set_use_underline(use_underline)

se “use_underline” è True, viene indicata con una sottolineatura, il carattere che dovrebbe essere
usato come accelerator key (il carattere nella label è anticipato da un underscore);
I parametri sono:
use_underline: il boolean che visualizza le accelerator keys;

Di seguito un codice d’esempio:

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


class GWindow(Gtk.Window):
    def __init__(self, controller=None):
        self.controller = controller
        super().__init__(title="Gtk3 Button")
        self.set_default_size(width=300, height=50)
        self.set_border_width(5)  # sets space around the inner widget (hbox)
        btn_ok = Gtk.Button.new_with_label("Click")
        image = Gtk.Image.new_from_file("OK24.png")
        btn_ok.set_image(image)
        btn_close = Gtk.Button.new_with_label("Close")
        hbox = Gtk.Box(spacing=3)  # spacing tra widgets
        self.add(hbox)

        # layout
        hbox.pack_start(child=btn_ok, expand=True, fill=True, padding=0)
        hbox.pack_start(child=btn_close, expand=True, fill=True, padding=0)
        hbox.set_homogeneous(True)

        # bindings
        btn_ok.connect("clicked", self.on_click)
        btn_close.connect("clicked", self.on_close)

    @staticmethod
    def on_click(button):
        label = "Click" if button.get_label() == "Clicked" else "Clicked"
        button.set_label(label=label)
        print("'%s' button was clicked" % label)

    @staticmethod
    def on_close(button):
        label = button.get_label()
        print("'%s' button was clicked" % label)
        Gtk.main_quit()


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

link di riferimento:

torna all’indice appunti
Gtk3 Button

Categorie:Gtk3, PyGObject, python Tag: , ,

PyGObject: Gtk.ToggleButton

13 Aprile 2020 Commenti chiusi

torna all’indice appunti

ToggleButton

Il widget Gtk.ToggleButton è molto simile al Gtk.Button, ma ha la particolarità di rimanere nello
stato in cui è, fino a che non viene ricliccato. Ovvero al click, rimane premuto fino a che non
viene ripremuto.
Quando lo stato del Gtk.ToggleButton cambia, viene emesso il segnale “toggled”.
Come per il Gtk.RadioButton è possibile ottenere lo stato del Gtk.ToggleButton, con il metodo
get_active():

Per creare un ToggleButton si utilizza il costruttore Gtk.ToggleButton(*args, **kwargs),
dove gli argomenti più significativi sono “”label” e “image”.
label: è una stringa di testo visualizzata nel ToggleButton
image: un oggetto Gtk.Image che rappresenta l’immagine sul
ToggleButton.

 
>>> tbutton = Gtk.ToggleButton()
>>> tbutton
<Gtk.ToggleButton object at 0xb4b9de3c (GtkToggleButton at 0x952b110)>

E’ possibile passare i parametri del widget in fase di costruzione, ma è possibile accedervi e
modificarli anche in seguito, utilizzando i metodi getter e setter get_property(property_name)
e set_property(property_name, property_value):

 
>>> tbutton.get_property("label")
>>> tbutton.set_property("label", "Button 1")
>>> tbutton.get_property("label")
'Button 1'

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

 
>>> tbutton.set_label("ToggleButton 1")
>>> tbutton.get_label()
'ToggleButton 1'

Per creare un ToggleButton, esistono due metodi “scorciatoia”:
new_with_label(label): dove “label” è il testo del togglebutton;
new_with_mnemonic(label): dove “label” è il testo con l’underscore davanti al
carattere “mnemonic”;

>>> button1 = Gtk.ToggleButton.new_with_label(label="Button 1")
>>> button2 = Gtk.ToggleButton.new_with_mnemonic(label="B_utton 2")

Image

Per inserire un’immagine all’interno del widget, creiamo prima un oggetto Gtk.Image e lo settiamo
nel widget che lo conterrà. Per recuperarla, si userà il getter specifico get_image()

 
>>> image = Gtk.Image.new_from_file("OK24.png")
>>> button1.set_image(image)
>>> button1.get_image() == image
True

Segnali

Per connettere un widget ad una callback, in modo che, quando viene emesso un segnale specifico,
quest’ultima venga invocata, si utilizza il metodo connect(signal, callback).
Il segnale che fondamentalmente interessa il ToggleButton è “toggled” e viene emesso quando un
ToggleButton, che precedentemente non era selezionato, viene cliccato (clicked()).
Per conoscere lo stato di un ToggleButton, si utilizza il metodo get_active()

 
>>> def on_button_toggled(button):
...     if button.get_active():
...         state = "on"
...     else:
...         state = "off"
...     print("{} was turned {}".format(button.get_label(), state))
...     
>>> button1.connect("toggled", on_button_toggled)
60
>>> button1.clicked()
Button 1 was turned on
>>> button1.get_active()
True
>>> button1.clicked()
Button 1 was turned off
>>> button1.get_active()
False
>>> button2.get_active()
False

Metodi

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

new()

Metodo costruttore che crea un nuovo Gtk.ToggleButton. I parametri possono essere settati
successivamente con i metodi setter dedicati (ad es. set_label(label);

new_with_label(label)

Crea un nuovo Gtk.ToggleButton con una label di testo associata.
Parametri:
label: il testo della label del ToggleButton;

new_with_mnemonic(label)

Crea un nuovo Gtk.ToggleButton con una label di testo dove un underscore anticipa il carattere
che verrà utilizzato come “mnemonic”.

 
>>> button2 = Gtk.ToggleButton.new_with_mnemonic(label="B_utton 2")

dove “u” sarà il mnemonic character per la scorciatoia da tastiera (ALT+u).
Parametri:
label: il testo del ToggleButton contenente gli mnemonic;

get_active()

Ritorna lo stato del togglebutton.

get_inconsistent()

ritorna True, se il togglebutton si trova nello stato inconsistent, ovvero quella
fase nè selezionato, nè deselezionato.

set_active(is_active)

Setta lo stato del togglebutton. Se is_active è True, il togglebutton verrà visualizzato come
selezionato. False ovviamente setterà il togglebutton come deselezionato.
Parametri:
is_active: il boolean che seleziona/deseleziona il ToggleButton;

set_inconsistent(is_inconsistent)

Setta lo stato del togglebutton a inconsistent, se is_inconsistent è True.
Parametri:
is_inconsistent: il boolean che setta il ToggleButton in uno stato
“inconsistent”, ovvero nè selezionato, nè deselezionato;

toggled()

Emette un segnale di tipo “toggled”.

clicked()

Emette un segnale di tipo “clicked”.

Di seguito un codice d’esempio:

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

class GWindow(Gtk.Window):
    def __init__(self):
        super().__init__(title="ToggleButton Demo")
        self.set_border_width(10)
        self.set_size(300, 100)

        hbox = Gtk.Box(spacing=6)
        self.add(hbox)

        button1 = Gtk.ToggleButton("Button 1")
        button2 = Gtk.ToggleButton("B_utton 2", use_underline=True)
        button2.set_active(True)
        # bindings
        button1.connect("toggled", self.on_button_toggled)
        button2.connect("toggled", self.on_button_toggled)
        # layout
        hbox.pack_start(button1, True, True, 0)
        hbox.pack_start(button2, True, True, 0)

    def on_button_toggled(self, button):
        button.set_inconsistent(False)
        if button.get_active():
            state = "on"
        else:
            state = "off"
        print("{} was turned {}".format(button.get_label(), 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 ToggleButton

Categorie:Gtk3, PyGObject, python Tag: , ,

PyGObject: Gtk.TreeStore

13 Aprile 2020 Commenti chiusi

torna all’indice appunti

TreeStore

Il widget Gtk.TreeStore fa parte del pattern model-view di GTK3.
Rispetto al ListStore è un model più complesso, poichè consente di gestire solo più livelli di
righe di dati, ovvero ogni row, può contenere una o più child-rows.
Come il ListStore è potente e flessibile e insieme alla view permette di avere le seguenti funzionalità:

– aggiornamento automatico dei dati quando questi vengono aggiunti, rimossi o modificati
– supporto al Drag and drop
– ordinamento dei dati
– incorporamento di widgets come checkboxes, progressbars, ecc.
– colonne riordinabili e ridimensionabili
– filtraggio dati

Model

Come già detto per il ListStore, ogni Gtk.TreeView ha un Gtk.TreeModel associato
che contiene i dati visualizzati dal widget treeview.
Un Gtk.TreeModel può essere utilizzato da più di un TreeView contemporaneamente.
Quando costruiamo il model, dobbiamo specificare che tipo di dati ogni colonna del model gestirà.
Il costruttore è pertanto Gtk.TreeStore(*column_types)

>>> treestore = Gtk.TreeStore(str, bool)

Questo crea un TreeStore con due colonne, una che conterrà un tipo str e una
con un tipo bool.
Per aggiungere i dati al TreeStore, si utilizza il metodo append(parent, row=None).
parent è il riferimento (iter) della row genitore, se parent = None, la row sarà
di tipo top-level, altrimenti, se parent sarà una row, avremo inserito una child-row.
Row è la lista con i valori da inserire nella row, che devono rispettare il type
definito precedentemente.

Il metodo append() ritorna un oggetto Gtk.TreeIter che punta alla posizione della
row appena inserita e può essere utilizzato in seguito per recuperare i valori dal treestore.

>>> import gi
... gi.require_version('Gtk', '3.0')
... from gi.repository import Gtk, Pango
>>> treestore = Gtk.TreeStore(str, bool)
>>> parent_iter1 = treestore.append(parent=None, row=["Portieri", False])  # top level row
>>> parent_iter2 = treestore.append(parent=None, row=["Difensori", False])  # top level row
>>> child_iter1 = treestore.append(parent=parent_iter1, row=["HANDANOVIC Samir", True])  # child row
>>> child_iter2 = treestore.append(parent=parent_iter2, row=["GODIN Diego", True])  # child row
>>> child_iter3 = treestore.append(parent=parent_iter2, row=["SKRINIAR Milan", True])  # child row

Una volta che i dati sono stati inseriti, è possibile recuperarli con gli stessi treeiters…

>>> treestore[parent_iter1]
<gi.overrides.Gtk.TreeModelRow object at 0x0000000004e070a0>
>>> treestore[parent_iter1][0]
'Portieri'
>>> treestore[child_iter2]
<gi.overrides.Gtk.TreeModelRow object at 0x00000000054cc280>
>>> treestore[child_iter2][0]
'GODIN Diego'

E’ ovviamente possibile iterare sui children di una row con gli appositi metodi, come ad esempio
iterchildren():

>>> for player in treestore[parent_iter2].iterchildren():
...      print(player[0])
...      
GODIN Diego
SKRINIAR Milan

Per conoscere il numero di top-level rows presenti nel treestore si utilizza il metodo len():

>>> len(treestore)
2

Path

Oltre ad accedere ai dati del treestore come si farebbe con le liste (via index), è possibile
farlo anche con Gtk.TreePath.
Questo treepath è un riferimento ad una certa row nel tree model e grazie al metodo get_iter()
è possibile ottenere l’iter desiderato.
In pratica, prima otteniamo l’oggetto generico relativo alla row desiderata di un treestore, ad
esempio vogliamo il riferimento della row 2.
Poi dal nostro treestore otteniamo l’oggetto iter relativo alla seconda row desiderata.
Una volta ottenuto l’iter, ricaviamo i valori:

>>> row2 = Gtk.TreePath(1)
>>> iter = treestore.get_iter(row2)
>>> treestore.get_value(iter, 0)
'Difensori'
>>> child = Gtk.TreePath().new_from_indices([1, 1])  # second row, second child
>>> iter = treestore.get_iter(child)
>>> treestore.get_value(iter, 0)
'SKRINIAR Milan'

Metodi

Vediamo quali sono i metodi utilizzabili con Gtk.TreeStore:

new(types)

Metodo costruttore che crea una nuova istanza di Gtk.TreeStore.
Parametri:
types: una lista di tipi rappresentanti il tipo di dato che le
colonne ospiteranno;

append(parent, row=None)

Aggiunge una nuova row di dati al TreeStore e ritorna l’oggetto Gtk.TreeIter che
si riferisce alla row appena aggiunta.
Parametri:
parent: l’oggetto Gtk.TreeIter di riferimento. Se parent=None,
la row aggiunta sarà di tipo top-level, altrimenti la row aggiunta, sarà figlia della row con iter
indicato in parent;
row: è la lista di valori da assegnare alla row appena aggiunta.
Se row è None, verrà aggiunta una row vuota e per inserire i dati in essa, sarà
necessario utilizzare i metodi Gtk.TreeStore.set() o Gtk.TreeStore.set_value().

clear()

Rimuove tutte le rows, top-level e child, dal TreeStore.

insert(parent, position, row=None)

Inserisce una nuova row alla posizione desiderata e ritorna l’oggetto Gtk.TreeIter relativo alla
row aggiunta.
Parametri:
parent: un oggetto Gtk.TreeIter valido, ovvero il
riferimento alla row genitore. Se parent=None, la row inserita sarà top-level, altrimenti sarà un
row figlia della row parent;
position: è il numero (int) relativo alla posizione dove vogliamo
aggiungere la row. Se parent è diverso da None, allora la posizione riguarderà le
children presenti. Se position=-1 o è maggiore del numero di rows presenti in quel livello, la
nuova row sarà inserita alla fine;
row: è la lista di valori da assegnare alla row appena aggiunta.
Se row è None, verrà aggiunta una row vuota e per inserire i dati in essa, sarà
necessario utilizzare i metodi Gtk.TreeStore.set() o Gtk.TreeStore.set_value().

insert_after(parent, sibling, row=None)

Inserisce una nuova row dopo sibiling e ritorna l’oggetto Gtk.TreeIter che si
riferisce alla row aggiunta.
Parametri:
parent: un oggetto Gtk.TreeIter valido, ovvero
il riferimento alla row genitore.
sibling: un oggetto Gtk.TreeIter valido, ovvero
il riferimento alla row, dopo la quale vogliamo inserire la nuova row, o None.
Se sibiling=None, la row verrà anteposta alle children di parent. Se anche parent=None, allora
verrà anteposta alle top-level row. Se sia sibiling che parent sono iter validi, allora parent
deve essere genitore di sibiling. Se sibilig esiste, parent è facoltativa;
row: è la lista di valori da assegnare alla row appena aggiunta.
Se row è None, verrà aggiunta una row vuota e per inserire i dati in essa, sarà
necessario utilizzare i metodi Gtk.TreeStore.set() o Gtk.TreeStore.set_value().

insert_before(parent, sibling, row=None)

Inserisce una nuova row prima di sibiling e ritorna l’oggetto Gtk.TreeIter che si
riferisce alla row aggiunta.
Parametri:
parent: un oggetto Gtk.TreeIter valido, ovvero il
riferimento alla row genitore.
sibling: un oggetto Gtk.TreeIter valido, ovvero
il riferimento alla row, prima della quale vogliamo inserire la nuova row, o None.
Se sibiling=None, la row verrà postposta dopo le children di parent. Se anche parent=None, allora
verrà postposta alle top-level row.
Se sia sibiling che parent sono iter validi, allora parent deve essere genitore di sibiling.
Se sibiling esiste, parent è facoltativa;
row: è la lista di valori da assegnare alla row appena aggiunta.
Se row è None, verrà aggiunta una row vuota e per inserire i dati in essa, sarà
necessario utilizzare i metodi Gtk.TreeStore.set() o Gtk.TreeStore.set_value().

insert_with_values(parent, position, columns, values)

Inserisce i dati, nelle colonne specificate, nella row di posizione desiderata e ritorna l’oggetto
Gtk.TreeIter che si riferisce alla row aggiunta.
Parametri:
parent: un oggetto Gtk.TreeIter valido, ovvero il
riferimento alla row genitore.
position: la posizione (int) dove inseriremo la row.
Se position=-1 o maggiore del numero di rows del TreeStore, verrà inserita in fondo (append);
columns: una lista con gli indici (int) delle colonne dove vogliamo
inserire i valori;
values: un lista di oggetti GObject.Value

is_ancestor(iter, descendant)

Ritorna True se iter è antenato di descendant;
antenato può ovviamente essere genitore di genitore, se abbiamo a che fare con sottolivelli di
sottolivelli:

>>> treestore.is_ancestor(parent_iter2, child_iter2)
True
>>> treestore.is_ancestor(parent_iter2, child_iter1)
False

Parametri:
iter: un oggetto Gtk.TreeIter valido;
descendant: un oggetto Gtk.TreeIter valido;

iter_depth(iter)

Ritorna un numero che indica il livello di profindità della row indicata da iter.
Tutto ciò che riguarda il livello top-level, dovrebbe essere 0, 1 per i sottolivelli al primo
strato e così via.

>>> treestore.iter_depth(parent_iter2)
0
>>> treestore.iter_depth(child_iter1)
1

Parametri:
iter: un oggetto Gtk.TreeIter valido;

iter_is_valid(iter)

Funzione da utilizzare in fase di debug, causa la lentezza; ritorna True se iter è valido.
Parametri:
iter: un oggetto Gtk.TreeIter;

move_after(iter, position)

Muove l’iter dopo la posizione specificata.
Questo metodo si utilizza solo con treestore non ordinati.
Parametri:
iter: l’oggetto Gtk.TreeIter da spostare;
position: l’oggetto Gtk.TreeIter dopo il quale spostare “iter”.
Se position=None, l’iter sarà spostato all’inizio del TreeStore.

move_before(iter, position)

Muove l’iter prima della posizione specificata.
Questo metodo si utilizza solo con treestore non ordinati.
Parametri:
iter: l’oggetto Gtk.TreeIter da spostare;
position: l’oggetto Gtk.TreeIter prima del quale spostare “iter”.
Se position=None, l’iter sarà spostato alla fine del TreeStore.

prepend(parent, row=None)

Antepone una nuova row al trestore.
Parametri:
parent: un oggetto Gtk.TreeIter valido, ovvero il
riferimento alla row genitore. Se parent=None, la nuova row sarà anteposta alle top-level rows
esistenti. Se parent è un iter esistente, la nuova row sarà una child anteposta alle children
esistenti per parent;
row: è la lista di valori da assegnare alla row appena aggiunta.
Se row è None, verrà aggiunta una row vuota e per inserire i dati in essa, sarà
necessario utilizzare i metodi Gtk.TreeStore.set() o Gtk.TreeStore.set_value().

remove(iter)

Rimuove la row con riferimento “iter” dal TreeStore e ritorna True se l’iter è valido, altrimenti
False ad operazione fallita. Se l’operazione ha buon fine, iter diventerà la row valida
successiva, oppure sarà invalidato se dovesse puntare all’ultima row del TreeStore.

set(iter, columns, values)

Setta i valori nelle colonne indicate, per la row con iter “iter”.
Parametri:
iter: l’oggetto Gtk.TreeIter indicante la row da modificare;
columns: una lista di indici relativi alle colonne interessate
dalla modifiche;
values: un lista di oggetti GObject.Value, ovvero i valori da
inserire nelle rispettive colonne;

set_column_types(types)

Funzione da utilizzare solo quando si costruisce un nuovo Gtk.TreeStore.
Non funziona dopo che una row è stata aggiunta o quando si utilizzano i metodi dell’interfaccia
di Gtk.TreeModel.
Parametri:
types: una lista di tipi rappresentanti il tipo di dato che le
colonne ospiteranno;

set_value(iter, column, value)

Setta i dati nella cella specificata da iter e column. Il valore “value” deve essere convertibile
nel tipo di dato previsto dalla colonna.
Il valore può essere Python value, inquanto sarà convertito in un oggetto GObject.Value.
Parametri:
iter: l’oggetto Gtk.TreeIter indicante la row da modificare;
column: il numero (int) di colonna nel quale inserire il valore;
value: l’oggetto GObject.Value da inserire nella cella definita da iter-column.

swap(a, b)

Inverte di posizione le row “a” e “b”.
Parametri:
a: il Gtk.TreeIter indicante la prima row da cambiare con la seconda;
b: il Gtk.TreeIter indicante la seconda row da cambiare con la prima;

View

La view è unica sia per un model TreeStore che per un model ListStore.
Settare un Gtk.TreeView è semplicissimo, dobbiamo solo fornirgli l’oggetto
Gtk.TreeModel dal quale attingere i dati, o passandolo il fase di costruzione,
come argomento, o utilizzando successivamente il metodo Gtk.TreeView.set_model().

>>> treeview = Gtk.TreeView(model=treestore)

Una volta che il treeview possiede un model, deve sapere come visualizzare i dati.
Qui entrano in gioco i column-renderers ed i cell-renderers.
I CellRenderers
sono usati per disegnare i dati del model nella view. GTK+ mette a disposizione cell-renderers
specifici, come Gtk.CellRendererText, Gtk.CellRendererPixbuf e Gtk.CellRendererToggle, ma è
possibile codificare un renderer personalizzato.

Il Gtk.TreeViewColumn è l’oggetto che Gtk.TreeView usa per organizzare le colonne.
Ha bisogno di conoscere le label per la colonna, che tipo di cell-renderer utilizzare e quale dato
ottenere dal model per una data row.

>>> treeview = Gtk.TreeView(model=treestore)
>>> renderer = Gtk.CellRendererText()
>>> column = Gtk.TreeViewColumn("Giocatore", renderer, text=0)
>>> treeview.append_column(column)
1

Selection

In questo tipo di widget molto probabilmente verranno effettuate delle selezioni.
Per poter accedere al contenuto della selezione, dobbiamo connettere il segnale “changed”
all’oggetto Gtk.TreeSelection.
Quindi dobbiamo recuperare un reference della selezione con il metodo get_selection():

>>> select = treeview.get_selection()
>>> def on_tree_selection_changed(selection):
...     model, treeiter = selection.get_selected()
...     if treeiter is not None:
...         print("You selected", model[treeiter][0])
...         
>>> select.connect("changed", on_tree_selection_changed)

E’ possibile controllare quali selezioni sono permesse chiamando il metodo Gtk.TreeSelection.set_mode().
Gtk.TreeSelection.get_selected() non funziona se il selection-mode è settato a
Gtk.SelectionMode.MULTIPLE, use invece Gtk.TreeSelection.get_selected_rows().

Sorting

il Sorting (ordinamento) è una delle caratteristiche più importanti del treeview
ed è supportata dai treemodels standard (Gtk.TreeStore and Gtk.TreeStore), che implementano
l’interfaccia Gtk.TreeSortable.

Sorting da colonna

Una colonna di un Gtk.TreeView può essere resa sortable semplicemente chiamando
il metodo Gtk.TreeViewColumn.set_sort_column_id().
In questo modo la colonna potrà essere ordinata semplicemente cliccando sulla sua intestazione.

>>> column.set_sort_column_id(0)

Se invece volessimo utilizzare una funzione di sorting personalizzata, dovremmo settarla con il
metodo set_sort_func().
Per prima cosa va definita la funzione di sorting che deve prendere 2 rows e confrontarle, se la
prima deve stare prima della seconda, la funzione ritorna -1, 0 se sono uguali in posizione
e 1 se la seconda row deve stare prima:

def compare(model, row1, row2, user_data):
    sort_column, _ = model.get_sort_column_id()
    value1 = model.get_value(row1, sort_column)
    value2 = model.get_value(row2, sort_column)
    if value1 < value2:
        return -1
    elif value1 == value2:
        return 0
    else:
        return 1

Poi la settiamo con il metodo set_sort_func().

>>> treestore.set_sort_func(0, compare, None)

Filtering

Diversamente dal sorting, il filtering non è gestito dai models, ma dalla classe
Gtk.TreeModelFilter.
Questa classe, come i Gtk.TreeStore e Gtk.TreeStore, è una Gtk.TreeModel.
Agisce come una “velina” davanti al model reale (Gtk.TreeStore o Gtk.TreeStore), nascondendo
alcuni elementi alla view.
In pratica fornisce il Gtk.TreeView con un set of the model sottostanti.
Si possono creare istanze di Gtk.TreeModelFilter, una sull’altra, in modo da utilizzare filtri
multipli sullo stesso model è possibile creare una nuova istanza di Gtk.TreeModelFilter e darle
un model da filtrare, ma il modo più semplice è usare direttamente il metodo Gtk.TreeModel.filter_new().

>>> filter = treestore.filter_new()

Nello stesso modo in cui lavora la funzione di sorting, il Gtk.TreeModelFilter necessita di una
funzione “visibility”, la quale, data una row dal modello sottostante, ritornerà un boolean
indicante se questa row deve essere filtrata o meno.
Questa funzione viene settata con il metodo Gtk.TreeModelFilter.set_visible_func():

>>> filter.set_visible_func(filter_func, data=None)

Ecco un codice di esempio:

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


players = [["Portieri",
            ["HANDANOVIC Samir", True], ["PADELLI Daniele", False],
            ["BERNI Tommaso", False]],
           ["Difesa",
            ["GODIN Diego", True], ["DE VRIJ Stefan", True],
            ["RANOCCHIA Andrea", False], ["ASAMOAH Keadwo", False],
            ["DIMARCO Federico", False], ["D'AMBROSIO Danilo", False],
            ["BIRAGHI Cristiano", True], ["SKRINIAR Milan", True],
            ["BASTONI Alessandro", False]],
           ["Centrocampo",
            ["GAGLIARDINI Roberto", False], ["VECINO Matias", False],
            ["SENSI Stefano", True], ["LAZARO Valentino", False],
            ["BORJA Valero", False], ["BARELLA Nicolò", True],
            ["BROZOVIC Marcelo", True], ["CANDREVA Antonio", True]],
           ["Attacco",
            ["SANCHEZ Alexis", False], ["LUKAKU Romelu", True],
            ["MARTINEZ Lautaro", True], ["ESPOSITO Sebastiano", False]]
           ]


class GWindow(Gtk.Window):
    def __init__(self):
        super().__init__(title="Library")
        self.set_default_size(250, 500)
        self.set_border_width(10)

        self.current_filter_role = None

        self.treestore = Gtk.TreeStore(str, bool)

        for i in range(len(players)):
            group = players[i]
            # Gtk.TreeStore.append(parent, [ruolo, titolare])
            parent_iter = self.treestore.append(None, [group[0], False])
            for player in group[1:]:  # il primo elemento è il ruolo e lo salto
                self.treestore.append(parent_iter, player)

        view = Gtk.TreeView()
        view.set_model(self.treestore)
        renderer_players = Gtk.CellRendererText()
        column_players = Gtk.TreeViewColumn("Giocatori", renderer_players,
                                            text=0)
        view.append_column(column_players)

        renderer_in_out = Gtk.CellRendererToggle()
        column_in_out = Gtk.TreeViewColumn("Titolari", renderer_in_out,
                                           active=1)
        view.append_column(column_in_out)

        renderer_in_out.connect("toggled", self.on_toggled)
        view.connect("row-activated", self.on_select_row)
        self.add(view)

    def on_toggled(self, widget, path):
        # il valore boolean della row che seleziono
        current_value = self.treestore[path][1]
        # eseguo il toggle del valore boolean della row che ho selezionato
        self.treestore[path][1] = not current_value
        # path ha un formato 'n' per top-level e 'n:n' per child
        if len(path) == 1:  # sto selezionando un ruolo (top level)
            parent_iter = self.treestore.get_iter(path)
            child_iter = self.treestore.iter_children(parent_iter)
            # il toggle sul ruolo si riflette su tutti i giocatori
            while child_iter is not None:  # child_iter=None sono in fondo
                self.treestore[child_iter][1] = not current_value
                child_iter = self.treestore.iter_next(child_iter)
        else:  # sto selezionando un giocatore
            selected_child_iter = self.treestore.get_iter(path)
            parent_iter = self.treestore.iter_parent(selected_child_iter)
            child_iter = self.treestore.iter_children(parent_iter)
            # controllo se tutti i children sono selezionati
            all_selected = True
            while child_iter is not None:
                if not self.treestore[child_iter][1]:
                    all_selected = False
                    break
                child_iter = self.treestore.iter_next(child_iter)
            # Se sono tutti selezionati, il ruolo viene selezionato
            self.treestore[parent_iter][1] = all_selected

    @ staticmethod
    def on_select_row(tree_view, path, column):
        print("INFO: '%s' selected!" % tree_view.get_model()[path][0])


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

link di riferimento:

torna all’indice degli appunti
Gnome gtk3 TreeStore
Gtk3 TreeStore

Categorie:Gtk3, PyGObject, python Tag:

PyGObject: Gtk.Stack, Gtk.StackSwitcher

13 Aprile 2020 Commenti chiusi

torna all’indice degli appunti

Stack

Il widget Gtk.Stack è un contenitore che mostra i suoi widget
uno alla volta. Le transizioni tra una “pagina” e l’altra, possono essere a scorrimento o sfumate
a seconda della preferenza. Tale animazione può essere settata con il metodo
Gtk.Stack.set_transition_type() e rispetta il settaggio “gtk-enable-animations” (Gtk.Setting).

Le properties principali del widget-parent contenitore sono:

Name Type Flags Short Description
always-show-image bool r/w/c/en Se l’immagine verrà sempre visualizzata
image Gtk.Widget r/w/en Il Child widget visualizzato a fianco del testo del button
image-position Gtk.PositionType r/w/en La posizione dell’immagine relativamente al testo
label str r/w/c/en Il testo del widget label nel button (se il button ne contiene una)
relief Gtk.ReliefStyle r/w/en Lo stile del bordo del button
use-underline bool r/w/c/en Se settato, l’underline prima di un carattere, ne identifica il mnemonic accelerator key
Name Type Flags Short Description
hhomogeneous bool r/w/en Se il sizing orizzontale è omogeneo
homogeneous bool r/w/en Se il sizing è Homogeneous
interpolate-size bool r/w/en Se la larghezza debba o meno cambiare passando da un child all’altro con size diversi
transition-duration int r/w/en La durata dell’animazione in millisecondi
transition-running bool r Se la transizione è in corso d’opera o meno
transition-type Gtk.StackTransitionType r/w/en Il tipo di animazione usata per la transizione
vhomogeneous bool r/w/en Se il sizing Verticale è omogeneo
visible-child Gtk.Widget r/w/en il widget attualmente visibile nello stack
visible-child-name str r/w/en Il nome del widget attualmente visibile nello stack

Le properties principali dei child widgets sono:

Name Type Flags Short Description
icon-name str None r/w Il nome dell’icona del child widget
name str None r/w Il nome del child widget
needs-attention bool False r/w Se il child widget necessita attenzione
position int 0 r/w L’indice del child widget nel parent widget
title str None r/w Il titolo del child widget

Metodi

Oltre ai soliti getter e setter relativi alle properties dell’oggetto Gtk.Stack, i principali
metodi sono:

new()

Crea un nuovo widget contenitore Gtk.Stack.

>>> import gi
... gi.require_version('Gtk', '3.0')
... from gi.repository import Gtk
... 
>>> stack = Gtk.Stack.new()

add_named(child, name)

Aggiunge una child-page allo stack. Il child è identificato dal nome.
Parametri:
child: il child (Gtk.Widget) da aggiungere allo stack;
name: il nome che identifica il child aggiunto allo stack;

add_titled(child, name, title)

Aggiunge una child-page allo stack. Il child è identificato dal nome.
Il titolo title sarà utilizzato dal Gtk.StackSwitcher (trattato più avanti)
per rappresentare il child nella tab bar.
Parametri:
child: il child (Gtk.Widget) da aggiungere allo stack;
name: il nome che identifica il child aggiunto allo stack;
title: il title da utilizzare per il child;

>>> label_1 = Gtk.Label("First page label")
>>> stack.add_titled(child=label_1, name="label_1", title="First page label")

get_child_by_name(name)

Ritorna il child widget che ha il nome passato come argomento, altrimenti None
se non ci sono children con quel nome.
Parametri:
name: il nome del child widget che vogliamo recuperare dallo stack;

>>> stack.get_child_by_name("label_1")
<Gtk.Label object at 0x0000000004f47400 (GtkLabel at 0x0000000004971260)>

get_hhomogeneous()

Ritorna True se lo stack ha un sizing orizzontale omogeneo.

get_homogeneous()

Ritorna True se lo stack ha un sizing omogeneo (sia orizzontale che verticale).

get_interpolate_size()

Ritorna True se lo stack esegue l’interpolazione tra le dimensioni dei children,
quando avviene lo switch tra le pagine.

get_transition_duration()

Ritorna la durata della transizione espressa in millisecondi.

get_transition_running()

Ritorna True se nello stack attualmente sta avvenendo una transizione

get_transition_type()

Ritorna il tipo di animazione (Gtk.StackTransitionType) che sarà usata nella transizione tra pagine.

get_vhomogeneous()

Ritorna True se lo stack ha un sizing verticale omogeneo.

get_visible_child()

Ritorna il child visibile corrente nello stack, o None, se non ci sono children visibili.

get_visible_child_name()

Ritorna il nome del child visibile corrente nello stack, o None se non ci sono children visibili.

set_hhomogeneous(hhomogeneous)

Setta se il Gtk.Stack debba avere un sizing orizzontale omogeneo o no. Se settiamo a True,
lo stack richiederà la stessa larghezza per tutti i suoi child widgets, altrimenti lo stack potrà
cambiare larghezza quando un child widget differente diventerà visibile.
Parametri:
hhomogeneous: il boolean che settato a True rende lo stack omogeneo orizzontalmente;

set_homogeneous(homogeneous)
Setta se il Gtk.Stack debba avere un sizing omogeneo (sia verticale che orizzontale) o no.
Se settiamo a True, lo stack richiederà lo stesso spazio per tutti i suoi child
widgets, altrimenti lo stack potrà cambiare dimensioni quando un child widget differente diventerà
visibile.
Parametri:
homogeneous: il boolean che settato a True rende
lo stack omogeneo (sia orizzontalmente che verticalmente);

set_interpolate_size(interpolate_size)

Setta se lo stack interpolerà le sue dimensioni quando cambia il child visibile.
Se la property di Gtk.Stack “:interpolate-size”=True, lo stack stesso interpolerà le proprie
dimensioni, tra quelle attuali e quelle che prenderà dopo la modifica del child visibile,
in accordo con la durata della transizione.
Parametri:
interpolate_size: Il boolean che settato a True
esegue l’interpolazione;

set_transition_duration(duration)

Setta la durata della transizione tra le “pagine”.
Parametri:
duration: la durata della transizione in millisecondi;

set_transition_type(transition)

Setta il tipo di animazione che sarà usata per la transizione tra pagine, nello stack.
Sono disponibili diversi tipi di animazioni a scorrimento e sfumate.
Parametri:
transition: l’oggetto Gtk.StackTransitionType
corrispondente all’animazione desiderata.

set_vhomogeneous(vhomogeneous)
Setta se il Gtk.Stack debba avere un sizing verticale omogeneo o no. Se settiamo a True,
lo stack richiederà la stessa altezza per tutti i suoi child widgets, altrimenti lo stack potrà
cambiare altezza quando un child widget differente diventerà visibile.
Parametri:
vhomogeneous: il boolean che settato a True rende lo stack omogeneo verticalmente;

set_visible_child(child)
Rende un widget il child visibile dello stack.
Se il widget è diverso dal child visibile corrente, avverrà la transizione in accordo con il
transition type corrente. Nota: il child widget deve essere esso stesso visibile
(Gtk.Widget.show()) per poter diventare il child visibile dello stack!
Parametri:
child: il child widget che vogliamo rendere visibile;

set_visible_child_full(name, transition)

Rende il widget con il nome passato come argomento, il child visibile dello stack e decide quale
transizione utilizzare.
Nota: il child widget deve essere esso stesso visibile (Gtk.Widget.show()) per
poter diventare il child visibile dello stack!
Parametri:
name: il nome del child widget che vogliamo rendere visibile;
transition: l’oggetto Gtk.StackTransitionType corrispondente all’animazione desiderata.

set_visible_child_name(name)

Rende il widget con il nome passato come argomento, il child visibile dello stack.
Se il widget è diverso dal child visibile corrente, avverrà la transizione in accordo con il
transition type corrente.
Nota: il child widget deve essere esso stesso visibile (Gtk.Widget.show()) per
poter diventare il child visibile dello stack!
Parametri:
name: il nome del child widget da rendere visibile;

StackSwitcher

Il widget Gtk.StackSwitcher agisce come controller dei widget Gtk.Stack.
In pratica visualizza una riga di bottoni per spostarsi tra le pagine associate allo stack widget.
I contenuti dei bottoni derivano dalle properties dei child del Gtk.Stack; la visibilità dei
bottoni nel widget Gtk.StackSwitcher è controllata dalla visibilità del child, nel Gtk.Stack.
E’ possibile associare multipli widget Gtk.StackSwitcher con lo stesso Gtk.Stack.

Le properties principali del widget StackSwitcher sono:

Name Type Flags Short Description
icon-size int r/w/en Symbolic size to use for named icon
stack Gtk.Stack r/w/c Stack

Metodi

Oltre ai soliti getter e setter relativi alle properties dell’oggetto Gtk.StackSwitcher,
i principali metodi sono:

new()

Crea un nuovo widget Gtk.StackSwitcher.

get_stack()

Ritorna il widget stack, settato con il metodo Gtk.StackSwitcher.set_stack().

set_stack(stack)

Setta il widget stack che sarà controllato dal widget StackSwitcher.
Parametri:
stack: il widget Gtk.Stack da controllare o None;

Di seguito un codice di esempio:

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


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

        stack = Gtk.Stack.new()
        stack.set_transition_type(Gtk.StackTransitionType.SLIDE_LEFT_RIGHT)
        stack.set_transition_duration(1000)

        checkbutton = Gtk.CheckButton(label="First page checkbutton")
        stack.add_titled(child=checkbutton, name="check", title="Check Button")

        label = Gtk.Label(label="Second page label")
        stack.add_titled(child=label, name="label", title="Label")

        stack_switcher = Gtk.StackSwitcher.new()
        stack_switcher.set_stack(stack)

        # layout
        vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6)
        vbox.pack_start(stack_switcher, True, True, 0)
        vbox.pack_start(stack, True, True, 0)
        self.add(vbox)


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 Stack
Gtk3 StackSwitcher

Categorie:Gtk3, PyGObject, python Tag: , ,

PyGObject: Gtk.Spinner

13 Aprile 2020 Commenti chiusi

torna all’indice degli appunti

Spinner

Il widget Gtk.Spinner è un widget provvisto di uno spinner animato e viene utilizzato come
alternativa alla progressbar classica, quando dobbiamo segnalare che l’applicazione sta eseguendo
delle operazioni. Non c’è molto da dire sull’animazione, se non che non è di tipo progressivo
(come la progressbar), che si attiva con il metodo start() e si interrompe con
il metodo stop().

Per creare un Spinner si utilizza il costruttore Gtk.Spinner(**kwargs).
L’unica proprietà è “active” ed è un boolean che indica se il widget è attivo o meno.

Metodi

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

new()

Metodo costruttore che crea un nuovo oggetto Gtk.Spinner.

start()

Avvia l’animazione dello spinner.

stop()

ferma l’animazione dello spinner.

Di seguito un codice d’esempio:

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


class GWindow(Gtk.Window):
    def __init__(self):
        super().__init__(title="Spinner")
        self.set_default_size(300, 200)
        self.set_border_width(3)

        button = Gtk.ToggleButton(label="Start")
        self.spinner = Gtk.Spinner()
        # layout
        vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=5)
        vbox.pack_start(button, True, True, 0)
        vbox.pack_start(self.spinner, True, True, 0)
        self.add(vbox)
        # bindings
        button.connect("toggled", self.on_button_toggled)

    def on_button_toggled(self, button):
        if button.get_active():
            self.spinner.start()
            button.set_label("Stop")
        else:
            self.spinner.stop()
            button.set_label("Start")


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 Spinner

Categorie:Gtk3, PyGObject, python Tag: , ,