Archivio

Archivio per la categoria ‘Gtk3’

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

TextView

Il widget Gtk.TextView viene utilizzato per visualizzare e modificare una grande quantità di
testo formattato. Come il Gtk.TreeView, sposa il pattern model/view.
In questo caso il Gtk.TextBuffer è il model che rappresenta il testo che deve
essere modificato. Questo permette a due o più widget Gtk.TextView di condividere lo stesso
Gtk.TextBuffer e permette a questi text buffers di essere visualizzati in maniera differente.

View

Il Gtk.TextView è il frontend con il quale lo user può aggiungere, editare e cancellare i dati
in formato testo. Viene comunemente usato per editare linee multiple di testo.
Quando creiamo un Gtk.TextView questo contiene il proprio Gtk.TextBuffer di default, al quale
possiamo accedere con il metodo Gtk.TextView.get_buffer().
Di default, il testo può essere aggiunto, editato e rimosso dal Gtk.TextView.
E’ possibile disabilitare questa caratteristica chiamando il metodo Gtk.TextView.set_editable().
Se il testo non è editabile può essere utile nascondere il cursore con il metodo
Gtk.TextView.set_cursor_visible().
E’ settabile anche il tipo di giustificazione, con il metodo Gtk.TextView.set_justification():
Gtk.Justification.LEFT): visualizza il testo giustificato a sinistra;
Gtk.Justification.RIGHT: visualizza il testo giustificato a destra;
Gtk.Justification.CENTER: visualizza il testo centrato;
Gtk.Justification.FILL: visualizza il testo riempiendo la riga.
Un altro settaggio di default è che le righe di testo molto lunghe, continuino orizzontalmente
oltre il bordo del TextView, fino a che non incontriamo un break.
Se vogliamo “wrappare” il testo per prevenire la fuoriuscita del testo dal bordo, utilizzare il
metodo Gtk.TextView.set_wrap_mode().

Model

Il Gtk.TextBuffer è il cuore del widget Gtk.TextView e viene usato per gestire
ogni aspetto del testo visualizzato nel Gtk.TextView.
Il settaggio del contenuto del TextBuffer è possibile con il metodo Gtk.TextBuffer.set_text(),
mentre per ottenerne il contenuto si utilizza il metodo Gtk.TextBuffer.get_text().
La maggiorparte delle manipolazioni del testo si ottengono con l’uso degli iterators,
rappresentati da istanze di Gtk.TextIter.
Un iterator rappresenta la posizione tra due caratteri in un text buffer.
Ogni volta che il buffer viene modificato nel proprio contenuto, tutti gli iterators
precedentemente creati, diventano invalidi.
Quindi gli iterators non possono essere usati per preservare la posizione durante le modifiche del
buffer. Per mantenere la posizione utilizzare un Gtk.TextMark.
Un text buffer contiene due built-in marks; un “insert” mark (che rappresenta la posizione del
cursoe) e il “selection_bound” mark. Entrambi possono essere recuperati rispettivamente con i
metodi Gtk.TextBuffer.get_insert() e Gtk.TextBuffer.get_selection_bound().
Di default, la posizione di un Gtk.TextMark non è mostrata, ma si può fare diversamente chiamando
il metodo Gtk.TextMark.set_visible().
Esistono molti metodi per recuperare un Gtk.TextIter.
Per esempio Gtk.TextBuffer.get_start_iter() ritorna un iterator che indica la
prima posizione nel text buffer, mentre Gtk.TextBuffer.get_end_iter(), ritorna un
iterator che indica l’ultimo carattere valido.
Per ottenere i limiti del testo selezionato si può utilizzare il metodo
Gtk.TextBuffer.get_selection_bounds().
Per inserire un testo in una posizione specifica, utilizzare il metodo Gtk.TextBuffer.insert().
Per inserire invece un testo nella posizione del cursore, usare Gtk.TextBuffer.insert_at_cursor().
Per rimuovere porzioni di text buffer usare il metodo Gtk.TextBuffer.delete().
Gtk.TextIter può anche essere usato per trovare testi nel buffer, usando la ricerca “in avanti”
con il metodo Gtk.TextIter.forward_search() e la ricerca all’indietro con il
metodo Gtk.TextIter.backward_search().

Tags

Il testo in un buffer può contenere i tags. Un tag è un attributo che può essere applicato ad una
porzione di testo. Ad esempio un tag chiamato “bold” permette alla porzione di testo racchiusa
tra i tags bold, di essere in grassetto. Qui il concetto è più generico, i tags non hanno effetto
solo sull’aspetto del testo, ma anche sul comportamento del mouse e sulla pressione dei tasti.
Ad esempio è possibile comprendere una porzione di testo tra tag ed evitare che questa possa
essere editata. Un tag viene rappresentato da un oggetto Gtk.TextTag.
Un singolo Gtk.TextTag può essere applicato a multiple porzioni di testo su multipli text buffers.
Ogni tag viene memorizzato in una Gtk.TextTagTable.
Una tagtable definisce un set di tags che possono essere usati insieme.
Ogni buffer ha una tagtable associata ad esso e solo i tags associati a tale tagtable possono
essere utilizzati su quel buffer. Una tagtable però può essere condivisa tra multipli buffers.
Per specificare che un testo nel buffer debba avere una specifica formattazione, dobbiamo definire
un tag con quelle informazioni di formattazione con il metodo Gtk.TextBuffer.create_tag()
e applicarlo al testo interessato con il metodo Gtk.TextBuffer.apply_tag():

tag = textbuffer.create_tag("orange_bg", background="orange")
textbuffer.apply_tag(tag, start_iter, end_iter)

Di seguito alcune delle properties più comuni
di text tag:

Background colour (“background” property)
Foreground colour (“foreground” property)
Underline (“underline” property)
Bold (“weight” property)
Italics (“style” property)
Strikethrough (“strikethrough” property)
Justification (“justification” property)
Size (“size” and “size-points” properties)
Text wrapping (“wrap-mode” property)

Per rimuovere un tag dal buffer si utilizza il metodo Gtk.TextBuffer.remove_tag();
per rimuovere invece tutti i tags di una regione, si usa il metodo Gtk.TextBuffer.remove_all_tags().

Le properties principali di Gtk.TextView sono:

Name Type Flags Short Description
accepts-tab bool r/w/en Se Tab risulta come inserimento di un carattere tab
bottom-margin int r/w/en L’altezza del margine inferiore in pixels
buffer Gtk.TextBuffer r/w Il buffer visualizzato
cursor-visible bool r/w/en Se il cursore di inserimento è visibile
editable bool r/w/en se il testo può essere modificato dallo user
im-module str r/w Quale IM (input method) module usare
indent int r/w/en La quantità di indentazione del paragrafo, in pixels
input-hints Gtk.InputHints r/w/en Hints per il comportamento del campo di testo
input-purpose Gtk.InputPurpose r/w/en Scopo del campo di testo
justification Gtk.Justification r/w/en La giustificazione (Left, right, o center)
left-margin int r/w/en Larghezza del margine sinistro in pixels
monospace bool r/w/en Se usare un font monospace
overwrite bool r/w/en Se il testo inserito sovrascrive quello esistente
pixels-above-lines int r/w/en Pixels di spazio vuoto sopra i paragrafi
pixels-below-lines int r/w/en Pixels di spazio vuoto sotto i paragrafi
pixels-inside-wrap int r/w/en Pixels di spazio vuoto tra le wrapped lines di un paragrafo
populate-all bool r/w/en Se emettere il segnale “populate-popup”
right-margin int r/w/en Larghezza del margine destro in pixels
tabs Pango.TabArray r/w tabs personalizzati per il testo
top-margin int r/w/en L’altezza del margine superiore in pixels
wrap-mode Gtk.WrapMode r/w/en Il wrap-mode utilizzato (never, word boundaries, o character boundaries)

Le properties relative allo style:

Name Type Default Flags Short Description
error-underline-color Gdk.Color None r Il colore con il quale indicare l’errore

Segnali

I principali segnali sono:

Name Short Description
backspace Il segnale “backspace” è un keybinding signal emesso quando lo user richiede il backspace
copy-clipboard Il segnale “copy-clipboard” è un keybinding signal emesso per copiare la selezione al clipboard
cut-clipboard Il segnale “cut-clipboard” è un keybinding signal emesso per “tagliare” la selezione al clipboard
delete-from-cursor Il segnale “delete-from-cursor” signal è un keybinding signal emesso quando lo user inizia a cancellare il testo
extend-selection Il segnale “extend-selection” viene emesso quando la selezione viene estesa
insert-at-cursor Il segnale “insert-at-cursor” è un keybinding signal emesso quando lo user inizia l’inserimento di un testo alla posizione del cursor
insert-emoji Il segnale “insert-emoji” è un keybinding signal emesso quando si attiva l’Emoji chooser
move-cursor Il segnale “move-cursor” è un keybinding signal emesso quando lo user inizia a spostare il cursore
move-viewport Il segnale “move-viewport” è un keybinding signal che può essere legato ad una combinazione di tasti con cui lo user muove il viewport
paste-clipboard Il segnale “paste-clipboard” è un keybinding signal emesso per incollare il contenuto del clipboard nel textview
populate-popup Il segnale “populate-popup” viene emesso prima di visualizzare il context menu del textview
preedit-changed Se viene usato un input method, il testo digitato non verrà inserito immediatamente nel buffer
select-all Il segnale “select-all” è un keybinding signal emesso per selezionare o deselezionare il contenuto completo del textview
set-anchor Il segnale “set-anchor” è un keybinding signal emesso quando lo user setta l “anchor” mark
toggle-cursor-visible Il segnale “toggle-cursor-visible” è un keybinding signal emesso quando cambia (toggle) la propertu “cursor-visible”
toggle-overwrite Il segnale “toggle-overwrite” è un keybinding signal emesso quando cambia (toggle) l’overwrite mode del text view

Metodi

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

new()

Crea un nuovo widget Gtk.TextView. Se prima di utilizzare il textview, non chiamiamo il metodo
Gtk.TextView.set_buffer(), un buffer di default vuoto verrà creato.
Il buffer si ottiene con il getter Gtk.TextView.get_buffer().
Per creare un nuovo textview con un proprio buffer, è consigliato l’utilizzo del costruttore

>>> import gi
... gi.require_version('Gtk', '3.0')
... from gi.repository import Gtk, Pango
>>> textview = Gtk.TextView.new()  # viene creato un buffer di default vuoto
>>> buffer = textview.get_buffer()  
>>> buffer
<Gtk.TextBuffer object at 0x00000000033d9fc0 (GtkTextBuffer at 0x0000000004ad6c80)>

Gtk.TextView.new_with_buffer().

new_with_buffer(buffer)

Crea un nuovo widget Gtk.TextView che visualizza il buffer passato in argomento.
Un buffer può essere condiviso tra multipli widgets.
Parametri:
buffer: un oggetto Gtk.TextBuffer. None per un buffer di default;

add_child_at_anchor(child, anchor)

Aggiunge un child widget nel text buffer, all’anchor dato.
Parametri:
child: un Gtk.Widget da inserire all’anchor dato;
anchor: un Gtk.TextChildAnchor alla cui pos. inserire il child;

add_child_in_window(child, which_window, xpos, ypos)

Aggiunge un child all coordinate date, nella window indicata.
La window deve avere una size maggiore di zero (vedi Gtk.TextView.set_border_window_size()).
Le coordinate del child sono relative allo scrolling. Quando piazziamo un child in una window
Gtk.TextWindowType.WIDGET, lo scrolling è irrilevante, ovvero il child è floattante su tutte le
aree scrollable. Se invece piazziamo un child in una delle scrollable windows (border windows o
text window) si sposterà come richiesto dallo scrolling.
Parametri:
child: un Gtk.Widget da aggiungere;
which_window: la Gtk.TextWindowType alla quale aggiungere il child;
xpos: la posizione X relativa alle coordinate di window;
ypos: la posizione Y relativa alle coordinate di window;

backward_display_line(iter)

Sposta l’iter indietro di una display line (wrapped).
Una display line è differente da un paragrafo. I paragrafi sono separati da newlines o altri
caratteri separatori di paragrafo.
Le xlib.Display lines sono create quando facciamo il line-wrapping di un paragrafo.
Se il wrapping non è attivo, le display lines e i paragrafi saranno gli stessi.
Le xlib.Display lines sono divise diversamente per ogni view, dal momento che dipendono dalla
larghezza della view; i paragrafi sono gli stessi in tutte le views, dal momento che dipendono
dai contenuti del Gtk.TextBuffer.
Parametri:
iter: l’oggetto Gtk.TextIter;

backward_display_line_start(iter)

Sposta l’iter all’inizio della display line (wrapped) precedente.
Parametri:
iter: l’oggetto Gtk.TextIter;

buffer_to_window_coords(win, buffer_x, buffer_y)

Converte le coordinate (buffer_x, buffer_y) in coordinate per la window win e ne memorizza i
valori in (window_x, window_y). Non si possono convertire coordinate per window non esistenti
(vedi Gtk.TextView.set_border_window_size()).
Parametri:
win: una Gtk.TextWindowType eccetto Gtk.TextWindowType.PRIVATE;
buffer_x: coordinate X del buffer;
buffer_y: coordinate Y del buffer;

forward_display_line(iter)

Sposta l’iter avanti di una display line (wrapped).
iter: l’oggetto Gtk.TextIter;

forward_display_line_end(iter)

Sposta l’iter alla fine della display line (wrapped) successiva.
Parametri:
iter: l’oggetto Gtk.TextIter;

get_accepts_tab()

Ritorna True se premendo il tasto Tab viene inserito un tab character,
altrimenti False, se premendo il tasto Tab, viene spostato il focus.

get_border_window_size(type)

Ritorna la larghezza del bordo della window specificata.
Vedere Gtk.TextView.set_border_window_size() per il corrispondente setter.
Parametri:
type: la window Gtk.TextWindowType;

get_bottom_margin()

Ritorna il valore del bottom margin in pixels.

get_buffer()

Ritorna il Gtk.TextBuffer associato al text view.

get_cursor_locations(iter)

Dato un iter all’interno di un text layout, determina le posizioni dello strong cursor
e del weak cursor se il punto di inserzione è a quell’iterator.
La posizione di ogni cursore viene memorizzata come zero-width rectangle.
La pozizione dello strong cursor è la posizione dove i caratteri della direzionalità
sono uguali alla direzione di base del paragrafo dove sono inseriti.
La posizione del weak cursor è la posizione dove i caratteri della direzionalità
sono opposti alla direzione di base del paragrafo dove sono inseriti.
Se l’iter è None, viene utilizzata la posizione corrente del cursore.
Se capita che l’iter sia la posizione corrente del cursore e ci sia un inserimento con
input method pre-edit, le posizioni ritornate dal metodo saranno aggiustate per tenere conto
dell’offset del cursore del pre-edit, all’interno della sequanza di pre-edit.
La posizione del rectangle è in coordinate del buffer; per convertirle in coordinate win, usare
Gtk.TextView.buffer_to_window_coords().
Parametri:
iter: il Gtk.TextIter o None;

get_cursor_visible()

Ritorna True se l’insertion mark del cursore è visibile.

get_default_attributes()

Ritorna una copia degli attributi di default del testo (Gtk.TextAttributes).

get_editable()

Ritorna True se il textview è editabile.

get_indent()

Ritorna l’indentazione di default dei paragrafi del textview.
I Tags del buffer potrebbero sovrascrivere i valori di default. L’indentazione potrebbe essere
negativa.

get_input_hints()

Ritorna il valore della property “input-hints”.

get_input_purpose()

Ritorna il valore della property “input-purpose”.

get_iter_at_location(x, y)

Ritorna una tupla (bool, iter).
Il primo elemento è True, se la posizione di iter o sopra al testo, altrimenti False.
Il secondo elemento è l’iterator con coordinate del buffer X e Y.
Le coordinate buffer sono relative all’intero buffer e non alla porzione visualizzata.
Se siamo in possesso di coordinate derivate da un event, dobbiamo convertirle in
coordinate buffer con il metodo Gtk.TextView.window_to_buffer_coords().
Parametri:
x: la posizione X in coordinate buffer;
y: la posizione Y in coordinate buffer;

get_iter_at_position(x, y)

Ritorna una tupla (bool, iter, trailing).
bool è True se la posizione dell’iterator è sopra al testo, altrimenti False.
iter è l’iterator che punta al carattere con coordinate buffer X e Y.
trailing è la posizione dove viene memorizzato l’intero che indica dove lo user ha
cliccato nel grafema (0 indica il bordo posteriore del grafema).
Le coordinate buffer sono relative all’intero buffer e non alla porzione visualizzata.
Se siamo in possesso di coordinate derivate da un event, dobbiamo convertirle in
coordinate buffer con il metodo Gtk.TextView.window_to_buffer_coords().
Questo metodo è differente dal precedente Gtk.TextView.get_iter_at_location(), il quale ritornaa
le posizioni del cursore, ad esempio le posizioni tra caratteri.
Parametri:
x: la posizione X in coordinate buffer;
y: la posizione Y in coordinate buffer;

get_iter_location(iter)

Ritorna un rettangolo (semplicemente gli estremi) che contengono approssimativamente il
carattere dell’iter. La posizione del rettangolo è in coordinate buffer.
Usare Gtk.TextView.buffer_to_window_coords() per convertirle da coordinate win.
Parametri:
iter: il Gtk.TextIter;

get_justification()

Ritorna la giustificazione di default del paragrafo nel textview.
I Tags nel buffer potrebbero sovrascrivere tale valore.

get_left_margin()

Ritorna il margine sinistro (in pixels) del paragrafo nel textview.
I Tags nel buffer potrebbero sovrascrivere tale valore.

get_line_at_y(y)

Ritorna una tupla (target_iter, line_top)
target_iter è il Gtk.TextIter all’inizio della linea che contiene la coordinata Y.
Y è espressa in coordinate buffer, convertirle in caso siano espresse in coordinate win, con il
metodo Gtk.TextView.window_to_buffer_coords().
line_top è la posizione della coordinata del TOP della linea.
Se diversa da None, line_top sarà riempita con le coordinate del bordo superiore della linea.
Parametri:
y: la coordinata Y;

get_line_yrange(iter)

Ritorna la coordinata Y del TOP della linea contenente l’iterator e l’altezza della linea.
Y è espressa in coordinata buffer; per convertirla usare Gtk.TextView.buffer_to_window_coords().
Parametri:
iter: il Gtk.TextIter;

get_monospace()

Ritorna il valore della property “monospace”.

get_overwrite()

Ritorna True se il textview è in modalità overwrite (sovrascrittura).

get_pixels_above_lines()

Ritorna il numero di pixels di default, da mettere sopra ai paragrafi.
Usare questo metodo insieme a Gtk.TextView.get_pixels_below_lines() uquivale a settare il
line-space tra paragrafi.

get_pixels_below_lines()

Ritorna il numero di pixels di default, da mettere sotto ai paragrafi.
Usare questo metodo insieme a Gtk.TextView.get_pixels_above_lines() uquivale a settare il
line-space tra paragrafi.

get_pixels_inside_wrap()

Ritorna il valore settato con il metodo Gtk.TextView.set_pixels_inside_wrap(), ovvero il numero di
pixels di spazio vuoto tra wrapped lines.

get_right_margin()

Ritorna il valore del margine destro del testo, in pixels.
I Tags nel buffer potrebbero sovrascrivere tale valore.

get_tabs()

Ritorna un oggetto Pango.TabArray, ovvero la lista dei tabs nel textview.
I Tags nel buffer potrebbero sovrascrivere il default.
L’oggetto ritornato potrebbe essere None se i tabs utilizzati saranno quelli standard di 8 spazi.

get_top_margin()

Ritorna il valore del margine superiore del testo, in pixels.

get_visible_rect()

Riempie “visible_rect” con la regione visibile corrente del buffer, in coordinates buffer.
Convertire, nel caso, le coordinate win con il metodo Gtk.TextView.buffer_to_window_coords().

get_window(win)

Ritorna la Gdk.Window corrispondente a un’area del textview. Le window possibili includono
complessivamente widget window, child windows su left, right, top, bottom e la window che
visualizza il text buffer.
Parametri:
win: il widget Gtk.TextWindowType ovvero la window richiesta;

get_window_type(window)

Di solito il metodo utilizzato per sapere a chi corrisponde un determinato evento.
Parametri:
window: il tipo di window (Gdk.Window);

get_wrap_mode()

Ritorna il line wrapping per la view.

im_context_filter_keypress(event)

Permette all’IM del Gtk.TextView di gestire internamente gli eventi key press e key release.
Se questo metodo ritorna True, nessun processo ulteriore verrà fatto per il key event specificato.
Vedere Gtk.IMContext.filter_keypress().
Parametri:
event: il key event (Gdk.EventKey);

move_child(child, xpos, ypos)

Sposta il child widget, alla posizione data.
Parametri:
child: il widget presente nel text view;
xpos: la nuova posizione X in coordinates window;
ypos: la nuova posizione Y in coordinates window;

move_mark_onscreen(mark)

Sposta un mark all’interno del buffer cosicchè sia piazzato all’interno della text area visibile.
Ritorna True se l’operazione avviene con successo.
Parametri:
mark: il Gtk.TextMark;

move_visually(iter, count)

Ritorna True se l’iter viene spostato e non è sull’end iterator.
Sposta l’iterator del numero di caratteri specificato, trattandolo come la posizione di uno
strong cursor. Se count è positivo, allora la nuova posizione
dello strong cursor sarà tante count posizioni verso destra, rispetto alla posizione del vecchio
cursore. Se count è negativo la nuova posizione dello strong cursor sarà
tante count posizioni a sinistra della posizione del vecchio cursore.
Parametri:
iter (Gtk.TextIter): il Gtk.TextIter;
count: il numero di caratteri di cui spostarsi (se count è
negativo si sposta a sinistra, se count è positivo, a destra);

place_cursor_onscreen()

Sposta il cursore nella regione visibile del buffer, e ritorna True se lo spostamento avviene con
successo.

reset_cursor_blink()

Assicura che il cursore sia visualizzato (senza che il intervallo di lampeggio sia “off”) e
resetta il tempo in cui resterà lampeggiante (o visibile, se il blinking è disabilitato).

reset_im_context()

Resetta il contesto dell’input method (IM) del text view, se necessario.
Questo è utile se la modifica del buffer rende il comportamento dell’IM in corso, confuso.

scroll_mark_onscreen(mark)

Scrolla il text view del minimo necessario, perchè il mark sia presente nell’are visibile.
Parametri:
mark: il Gtk.TextMark nel buffer;

scroll_to_iter(iter, within_margin, use_align, xalign, yalign)

Scrolla il text view in modo che l’iterator sia sullo schermo nella posizione indicata da xalign
e yalign. Un allineamento di 0.0 indica sinistra, o top; 1.0 indica destra,
o bottom; 0.5 singnifica centrato.
Se use_align è False, il testo scrolla la distanza minima per avere il mark sullo
schermo, possibilmente non scrollando affatto.
Lo schermo effettivo per lo scopo di questo metodo è ridotto di un margine di within_margin.
Questo metodo usa l’altezza calcolata delle linee correnti, nel text buffer.
Le altezze delle linee sono calcolate in un idle handler; così facendo con questo metodo non si
otterrà l’effetto desiderato se questo verrà chiamato prima del calcolo dell’altezza.
Per evitare effetti strani, utilizzare il metodo Gtk.TextView.scroll_to_mark() che salva un punto
su cui scrollare, quando la validazione delle linee sarà terminato.
Parametri:
iter: il Gtk.TextIter;
within_margin: il margine come 0.0, 0.5 frazione di schermo;
use_align: se utilizzare gli argomenti di alignment (se False,
si occupa solo di avere il mark sullo schermo;
xalign: l’alignment orizzontale del mark, nell’area visibile;
yalign: l’alignment verticale del mark, nell’area visibile;

scroll_to_mark(mark, within_margin, use_align, xalign, yalign)

Scrolla il text view in modo che il mark sia sullo schermo nella posizione indicata da xalign
e yalign. Un allineamento di 0.0 indica sinistra, o top; 1.0 indica destra,
o bottom; 0.5 singnifica centrato.
Se use_align è False, il testo scrolla la distanza minima per avere il mark sullo
schermo, possibilmente non scrollando affatto.
Lo schermo effettivo per lo scopo di questo metodo è ridotto di un margine di within_margin.
Parametri:
mark: il Gtk.TextMark);
within_margin: il margine come 0.0, 0.5 frazione di schermo;
use_align: se utilizzare gli argomenti di alignment (se False,
si occupa solo di avere il mark sullo schermo;
xalign: l’alignment orizzontale del mark, nell’area visibile;
yalign: l’alignment verticale del mark, nell’area visibile;

set_accepts_tab(accepts_tab)

Setta il comportamento del text view quando viene premuto il Tab key.
Se accepts_tab è True, un carattere tab viene inserito. If accepts_tab è False
il focus viene spostato sul child successivo della focus chain.
Parametri:
accepts_tab il boolean che decide se inserire un carattere di tab
(True) o spostare il focus (False);

set_border_window_size(type, size)

Setta la larghezza del bordo ai seguenti valori dell’enum Gtk.TextWindowType:
PRIVATE (0): valore non valido, usato come marker;
WIDGET (1): window floattante sulle aree di scroll;
TEXT (2): scrollable text window;
LEFT (3): il bordo sinistro della window;
RIGHT (4): il bordo destro della window;
TOP (5): il bordo superiore della window;
BOTTOM (6): il bordo inferiore della window;
Parametri:
type: il Gtk.TextWindowType sul quale applicare il size;
size: larghezza, o altezza, della window;

set_bottom_margin(bottom_margin)

Setta il margine inferiore del testo nel text view. Il nome del metodo può confondere, ma in
termini di CSS, settiamo il valore del padding.
Parametri:
bottom_margin: il margine inferiore in pixels;

set_buffer(buffer)

Setta il buffer da visualizzare nel text view.
Parametri:
buffer: il Gtk.TextBuffer da visualizzare nel text view, o None;

set_cursor_visible(setting)

Setta la visibilità del cursore. Ad esempio in un buffer non editabile è giustificabile non voler
vedere il cursore.
Parametri:
setting: il boolean che rende visibile o meno il cursore;

set_editable(setting)

Setta l’editabilità del Gtk.TextView. E’ possibile sovrascrivere questo settaggio con i tags
nel buffer, usando l’attributo del tag “editable”.
Parametri:
setting: il boolean che rende il text view editabile o meno;

set_indent(indent)

Setta l’indentazione di default per i paragrafi del text view.
I Tags nel buffer potrebbero sovrascrivere questo settaggio..
Parametri:
indent: l’indentazione in pixels;

set_input_hints(hints)

Setta la property “input-hints” che permette agli input methods (IM) di affinare il proprio
comportamento.
Parametri:
hints: i Gtk.InputHints da settare;

set_input_purpose(purpose)

Setta la property “input-purpose” che può essere usata dalle on-screen keyboards e altri IM.
Parametri:
purpose: il Gtk.InputPurpose;

set_justification(justification)

Setta la giustificazione del testo nel text view.
I valori possono essere Gtk.Justification.LEFT, Gtk.Justification.RIGHT, Gtk.Justification.CENTER,
Gtk.Justification.FILL. I Tags nel buffer potrebbero sovrascrivere questo settaggio.
Parametri:
justification: il Gtk.Justification (LEFT, RIGHT, CENTER, FILL);

set_left_margin(left_margin)

Setta il valore in pixels del margine sinistro del testo (inteso come padding).
I Tags nel buffer potrebbero sovrascrivere questo settaggio.
Parametri:
left_margin: il margine sinistro (padding) in pixels;

set_monospace(monospace)

Setta la property “monospace”, che indica che il text view deve usare o meno fonts monospace.
Parametri:
monospace: il boolean che setta, o meno, lo styling monospace;

set_overwrite(overwrite)

Setta la modalità sovrascrittura (overwrite mode) del text view.
Parametri:
overwrite: il boolean che setta, o meno, l’ overwrite mode;

set_pixels_above_lines(pixels_above_lines)

Setta il numero di pixels vuoti sopra ai paragrafi.
I Tags nel buffer potrebbero sovrascrivere questo settaggio.
Parametri:
pixels_above_lines: il numero di blank pixels sopra ai paragrafi;

set_pixels_below_lines(pixels_below_lines)

Setta il numero di pixels di spazio vuoto da mettere sotto ai paragrafi.
I Tags nel buffer potrebbero sovrascrivere questo settaggio.
Parametri:
pixels_below_lines: il numero di pixels vuoti sotto ai paragrafi;

set_pixels_inside_wrap(pixels_inside_wrap)

Setta il numero di pixels di spazio vuoto dalasciare tra le wrapped lines dentro a un paragrafo.
I Tags nel buffer potrebbero sovrascrivere questo settaggio.
Parametri:
pixels_inside_wrap: il numero di pixels vuoti tra wrapped lines;

set_right_margin(right_margin)

Setta il valore in pixels del margine destro del testo (inteso come padding).
I Tags nel buffer potrebbero sovrascrivere questo settaggio.
Parametri:
right_margin: il margine destro (padding) in pixels;

set_tabs(tabs)

Setta i tab stops per i paragrafi nel text view.
I Tags nel buffer potrebbero sovrascrivere questo settaggio.
Parametri:
tabs: un oggetto Pango.TabArray;

set_top_margin(top_margin)

Setta il margine superiore per il testo, inteso come padding).
Parametri:
top_margin: il margine superiore (padding) in pixels;

set_wrap_mode(wrap_mode)

Setta il line wrapping per il text view. L’enum che lo definisce, può assumere i seguenti valori:
NONE (0): nessun wrap;
CHAR (1): esegue il wrap del testo, ovunque il cursore possa apparire (tra i caratteri);
WORD (2): esegue il wrap del testo, spezzando la linea tra parole intere;
WORD_CHAR (3): esegue il wrap del testo, spezzando la linea tra parole, o, se non è sufficiente,
anche tra grafemi;
Parametri:
wrap_mode: l’enum (Gtk.WrapMode) che definisce il wrap mode;

starts_display_line(iter)

Ritorna True se un iter è all’inizio di una display line, altrimenti False.
vedere Gtk.TextView.forward_display_line() per la differenza tra display lines e paragrafi.
Parametri:
iter: l’oggetto Gtk.TextIter da verificare;

window_to_buffer_coords(win, window_x, window_y)

Converte le coordinate sulla window identificate da win, in coordinate buffer.
Ritorna una tupla (buffer_x, buffer_y).
Parametri:
win: una Gtk.TextWindowType eccetto Gtk.TextWindowType.PRIVATE
window_x: le coordinate window X da convertire;
window_y: le coordinate window Y da convertire;

Ecco 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_bold.connect("clicked", self.on_button_clicked, self.tag_bold)
        # Button Italic
        button_italic = Gtk.ToolButton()
        button_italic.set_icon_name("format-text-italic-symbolic")
        toolbar.insert(button_italic, 1)
        button_italic.connect("clicked", self.on_button_clicked,
                              self.tag_italic)
        # Button underline
        button_underline = Gtk.ToolButton()
        button_underline.set_icon_name("format-text-underline-symbolic")
        toolbar.insert(button_underline, 2)
        button_underline.connect("clicked", self.on_button_clicked,
                                 self.tag_underline)

        toolbar.insert(Gtk.SeparatorToolItem(), 3)
        # RadioButtons
        radio_j_left = Gtk.RadioToolButton()
        radio_j_left.set_icon_name("format-justify-left-symbolic")
        toolbar.insert(radio_j_left, 4)

        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)

        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)

        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)

        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)

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

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

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

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

    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("This is some text inside of a Gtk.TextView. "
                                  "Select text and click one of the buttons "
                                  "'bold', 'italic', or 'underline' to modify "
                                  "the text accordingly.")
        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)
        check_editable.connect("toggled", self.on_editable_toggled)
        self.grid.attach(check_editable, 0, 2, 1, 1)

        check_cursor = Gtk.CheckButton(label="Cursor Visible")
        check_cursor.set_active(True)
        check_editable.connect("toggled", self.on_cursor_toggled)
        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)

        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)

    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
changed il segnale “changed” viene emesso quando cambia l’elemento “attivo”;
format-entry-text usato quando il combobox prevede una entry;
move-active il segnale “move-active” viene emesso quando si sposta la selezione attiva;
popdown il segnale “popdown” è un keybinding emesso quando si apre la lista della combobox con la combinazione ALT+UP;
popup il segnale “popup” è un keybinding emesso quando si chiude la lista della combobox con la combinazione ALT+DOWN;

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


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

        name_store = Gtk.ListStore(int, str)
        name_store.append([1, "Billy Bob"])
        name_store.append([11, "Billy Bob Junior"])
        name_store.append([12, "Sue Bob"])
        name_store.append([2, "Joey Jojo"])
        name_store.append([3, "Rob McRoberts"])
        name_store.append([31, "Xavier McRoberts"])

        name_combo = Gtk.ComboBox.new_with_model_and_entry(name_store)
        name_combo.connect("changed", self.on_name_combo_changed)
        name_combo.set_entry_text_column(1)

        vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6)
        vbox.pack_start(name_combo, False, False, 0)

        country_store = Gtk.ListStore(str)
        countries = ["Austria", "Brazil", "Belgium", "France", "Germany",
                     "Switzerland", "United Kingdom",
                     "United States of America", "Uruguay"]
        for country in countries:
            country_store.append([country])

        country_combo = Gtk.ComboBox.new_with_model(country_store)
        country_combo.connect("changed", self.on_country_combo_changed)
        renderer_text = Gtk.CellRendererText()
        country_combo.pack_start(renderer_text, True)
        country_combo.add_attribute(renderer_text, "text", 0)
        vbox.pack_start(country_combo, False, False, True)

        currencies = ["Euro", "US Dollars", "British Pound", "Japanese Yen",
                      "Russian Ruble", "Mexican peso", "Swiss franc"]
        currency_combo = Gtk.ComboBoxText()
        currency_combo.set_entry_text_column(0)
        currency_combo.connect("changed", self.on_currency_combo_changed)
        for currency in currencies:
            currency_combo.append_text(currency)

        vbox.pack_start(currency_combo, False, False, 0)
        self.add(vbox)

    def on_name_combo_changed(self, combo):
        tree_iter = combo.get_active_iter()
        if tree_iter is not None:
            model = combo.get_model()
            row_id, name = model[tree_iter][:2]
            print("Selected: ID=%d, name=%s" % (row_id, name))
        else:
            entry = combo.get_child()
            print("Entered: %s" % entry.get_text())

    def on_country_combo_changed(self, combo):
        tree_iter = combo.get_active_iter()
        if tree_iter is not None:
            model = combo.get_model()
            country = model[tree_iter][0]
            print("Selected: country=%s" % country)

    def on_currency_combo_changed(self, combo):
        text = combo.get_active_text()
        if text is not None:
            print("Selected: currency=%s" % text)


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: , ,