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

PyGObject: Gtk.Popover

13 Aprile 2020

torna all’indice appunti

Popover

Il widget Gtk.Popover è una window contestuale che contiene opzioni o informazioni.
I Popovers vengono allegati ad un widget, passati in fase di costruzione su Gtk.Popover.new(),
o aggiornati successivamente con il metodo Gtk.Popover.set_relative_to().
Di default punteranno all’intera area del widget, ma tale comportamento può essere modificato con
il metodo Gtk.Popover.set_pointing_to().
La posizione di un popover relativamente al widget al quale è allegato, può anche essere cambiata
con il metodo Gtk.Popover.set_position().
Di default, il Gtk.Popover esegue un GTK+ grab, per assicurarsi gli input events
fintanto che rimane visualizzato, mentre scompare quando si clicca nell’area circostante ad esso,
o viene premuto il tasto Esc.
Se non si desidera un comportamento “modal” sul popover, è possibile utilizzare il metodo
Gtk.Popover.set_modal() per modificarlo, settando infatti a False, il popover non
eseguirà un GTK+ grab sugli input events.

Le properties principali sono:

Name Type Flags Short Description
constrain-to Gtk.PopoverConstraint r/w/en costringe il popover nella posizione data
modal bool r/w/en Setta il popover in modalità modal (esegue Gtk+ grab sugli input events)
pointing-to Gdk.Rectangle r/w dove punta la bubble window del popover
position Gtk.PositionType r/w/en dove posizionare la bubble window del popover
relative-to Gtk.Widget r/w Il Widget al quale la bubble window punta

Segnali

Name Short Description
closed viene emesso quando il popover viene dismesso

Metodi

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

add(widget)

Ereditato da Gtk.Container, aggiunge un widget al popover.
Questo widget a sua volta può essere un contenitore di altri widgets.
Parametri:
widget: l’oggetto Gtk.Widget da inserire nel popover;

new(relative_to)

Crea un nuovo oggetto Gtk.Popover che punterà al widget relative_to.
Parametri:
relative_to: l’oggetto Gtk.Widget al quale il popover farà riferimeno;

new_from_model(relative_to, model)

Crea un nuovo oggetto Gtk.Popover che punterà al widget relative_to e lo popola
in accordo con l’oggetto model. I buttons creati sono connessi alle actions
trovate nel Gtk.ApplicationWindow al quale il popover appartiene
Parametri:
relative_to: il Gtk.Widget al quale si riferisce il popover;
model: un Gio.MenuModel;

bind_model(model, action_namespace)

Stabilisce una connessione tra un Gtk.Popover e un Gio.MenuModel.
I contenuti del popover vengono rimossi e ripopolati in accordo con gli elementi del model.
Quando il model cambia, il popover si aggiorna.
Se si chiama questo metodo due volte con differenti models, il primo binding verrà rimpiazzato
dal secondo. Se il model è None ogni binding precedente viene eliminato e tutti
i children rimossi. Se action_namespace esiste (diverso da None) allora tutte le
azioni menzionate nel model avranno un prefisso, ad esempio l’azione “quit” con action_namespace
“app”, avrà un nome effettivo uguale a “app.quit”.
Questa funzione utilizza Gtk.Actionable per definire il nome della action e i target
values sugli elementi creati nel menu. Se vogliamo usare un action group diverso da “app” e “win”,
dobbiamo aggiungere il nostro action group personalizzato alla gerarchia di widget, usando il
metodo Gtk.Widget.insert_action_group(), ad esempio se creiamo un action_group
“mygroup”, la action “info” ad esso relativa, nel nostro oggetto Gio.MenuModel,
avrà un nome “mygroup.quit”.
Parametri:
model: il Gio.MenuModel a cui legarsi o None per non avere binding;
action_namespace: il namespace per le actions nel model;

get_constrain_to()

Ritorna l’oggetto Gtk.PopoverConstraint per il
piazzameno del popover. Il PopoverConstraint è un enum che descrive i vincoli per il
posizionamento del popover. Può assumere due valori:
NONE (0): non vincola il posizionamento del popover;
WINDOW (1): vincola il posizionamento ai margini della window alla quale il popover è allegato;

get_default_widget()

Ritorna il widget che dovrebbe essere settato come default mentre il popover viene visualizzato,
o None se non presente.

get_modal()

Ritorna True se il popover è impostato come modal, ovvero esegue
il Gtk+ grab sugli input events, come il click sull’area circostante al popover,
o la pressione del tasto Esc.

get_pointing_to()

Ritorna True, se è stato settato un oggetto Gdk.Rectangle
al quale popover deve puntare (vedere il metodo set_pointing_to()) e il Gdk.Rectangle
corrispondente, altrimenti False con il Gdk.Rectangle relativo al widget al quale è stato
allegato il popover.

>>> popover1 = Gtk.Popover()
>>> popover1.get_pointing_to()
(False, rect=<Gdk.Rectangle object at 0x0000000003c011c0 (GdkRectangle at 0x00000000049451c0)>)

get_position()

Ritorna la posizione del popover. La posizione è un oggetto di tipo Gtk.PositionType

get_relative_to()

Ritorna il widget al quale il popover è stato allegato

>>> button = Gtk.Button.new_with_label("Click Me")
>>> popover.set_relative_to(button)
>>> popover.get_relative_to().get_label()
'Click Me'

popdown()

Nasconde il popover menu mediante transizione.
Non è la stessa cosa che chiamare il metodo Gtk.Widget.hide()

popup()

Visualizza il popover mediante transizione.
Non è la stessa cosa che chiamare il metodo Gtk.Widget.show()

set_constrain_to(constraint)

Setta un vincolo per il posizionamento del popover.
Parametri:
constraint: un oggetto Gtk.PopoverConstraint.
Il PopoverConstraint è un enum che descrive i vincoli per il posizionamento del popover.
Può assumere due valori:
NONE (0): non vincola il posizionamento del popover;
WINDOW (1): vincola il posizionamento ai margini della window alla quale il popover è allegato;

set_default_widget(widget)

Setta il widget che dovrebbe essere settato come default quando il popover viene visualizzato.
Il popover tiene traccia del precedente widget di default, che ripristinerà una volta che il
popover stesso scomparirà.
Parametri:
widget: il nuovo widget di default da usare mentre il popover
viene visualizzato, o None;

set_modal(modal)

Setta il popover come modal, ovver lo stesso reclamerà tutti gli input events all’interno della
top level window (Gtk+ grab)

set_pointing_to(rect)

Setta il rettangolo (trasparente) al quale punterà il popover con il suo indicatore.
Parametri:
rect: un oggetto Gdk.Rectangle a cui puntare

>>> import gi
... gi.require_version('Gtk', '3.0')
>>> from gi.repository import Gtk, Gdk
>>> popover = Gtk.Popover()
>>> rect = Gdk.Rectangle()
>>> rect.x = 50
... rect.y = 50
... rect.height = 200
>>> popover.set_pointing_to(rect)

set_position(position)

Setta la posizione desiderata dove far apparire il popover.
Questa posizione viene rispettata quando lo spazio lo consente.
Parametri:
position: un enum di tipo Gtk.PositionType che indica la
posizione desiderata per il popover;

set_relative_to(relative_to)

Setta un nuovo widget al quale allegare il popover.
Parametri:
relative_to: il widget al quale allegare il popover;

Di seguito un codice di esempio:

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


class GWindow(Gtk.Window):
    def __init__(self):
        super().__init__(title="Popover Demo")
        self.set_border_width(10)
        self.set_default_size(400, 200)

        button = Gtk.Button.new_with_label("Click Me")
        pop_open_button = Gtk.ModelButton(label="Open")
        pop_quit_button = Gtk.ModelButton(label="Quit")
        # layout
        hbox = Gtk.Box(spacing=6, orientation=Gtk.Orientation.VERTICAL)
        hbox.pack_start(button, False, True, 0)
        popover_vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
        popover_vbox.pack_start(pop_open_button, False, True, 10)
        popover_vbox.pack_start(pop_quit_button, False, True, 10)
        self.popover = Gtk.Popover()
        self.popover.add(popover_vbox)  # add a container 
        self.popover.set_position(Gtk.PositionType.BOTTOM)
        self.add(hbox)
        # bindings
        button.connect("clicked", self.on_click)
        pop_open_button.connect("clicked", self.on_popover_open)
        pop_quit_button.connect("clicked", self.on_popover_quit)
        self.popover.connect("closed", self.popover_dismissed)

    def popover_dismissed(self, popover):
        print("INFO: Popover dismissed!")

    def on_click(self, button):
        self.popover.set_relative_to(button)
        self.popover.show_all()
        self.popover.popup()

    def on_popover_open(self, button):
        print("INFO: '%s' button was clicked" % button.get_label())

    def on_popover_quit(self, button):
        Gtk.main_quit()


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

Gtk.Popover al posto dei menu

Il Gtk.Popover è spesso usato come alternativa ai menu e viene popolato da un Gio.MenuModel,
usando il metodo Gtk.Popover.new_from_model().
In aggiunta a tutte le caratteristiche di un menu model, questo metodo supporta la renderizzazione
di icon buttons, al posto dei classici elementi del menu.
Per sfruttare questa caratteristica, nella stringa XML, settare l’attributo “display-hint” della
sezione a horizontal-buttons e settare le icone degli elementi del menu con
l’attributo “verb-icon”.

<section>
  <attribute name="display-hint">horizontal-buttons</attribute>
  <item>
    <attribute name="label">Cut</attribute>
    <attribute name="action">app.cut</attribute>
    <attribute name="verb-icon">edit-cut-symbolic</attribute>
  </item>
  <item>
    <attribute name="label">Copy</attribute>
    <attribute name="action">app.copy</attribute>
    <attribute name="verb-icon">edit-copy-symbolic</attribute>
  </item>
  <item>
    <attribute name="label">Paste</attribute>
    <attribute name="action">app.paste</attribute>
    <attribute name="verb-icon">edit-paste-symbolic</attribute>
  </item>
</section>

Ecco un codice di esempio con entramni i casi di popover:

import sys

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


MENU_XML = """
<?xml version="1.0" encoding="UTF-8"?>
<interface>
  <menu id="app-menu">
    <section>
        <item>
            <attribute name="label">About</attribute>
            <attribute name="action">app.about</attribute>
        </item>
        <item>
            <attribute name="label">Quit</attribute>
            <attribute name="action">app.quit</attribute>
        </item>
    </section>
  </menu>
  <menu id="app-menu-icon">
    <section>
    <attribute name="display-hint">horizontal-buttons</attribute>
        <item>
            <attribute name="label">Cut</attribute>
            <attribute name="action">app.cut</attribute>
            <attribute name="verb-icon">edit-cut-symbolic</attribute>
        </item>
        <item>
            <attribute name="label">Copy</attribute>
            <attribute name="action">app.copy</attribute>
            <attribute name="verb-icon">edit-copy-symbolic</attribute>
        </item>
    </section>
  </menu>
</interface>
"""


class AppWindow(Gtk.ApplicationWindow):
    def __init__(self, *args, **kwargs):
        print("OK")
        super().__init__(*args, **kwargs)
        self.set_default_size(300, 200)
        self.set_border_width(50)

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

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

        menu = builder.get_object("app-menu")
        button = Gtk.MenuButton.new()
        popover = Gtk.Popover.new_from_model(button, menu)
        button.set_popover(popover)

        menu_icon = builder.get_object("app-menu-icon")
        button_icon = Gtk.MenuButton.new()
        popover_icon = Gtk.Popover.new_from_model(button_icon, menu_icon)
        button_icon.set_popover(popover_icon)
        # layout
        outerbox.pack_start(button, False, True, 0)
        outerbox.pack_start(button_icon, False, True, 0)
        self.show_all()


class Application(Gtk.Application):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, application_id="org.example.myapp", **kwargs)
        self.window = None

    def do_startup(self):
        Gtk.Application.do_startup(self)

        action = Gio.SimpleAction.new("about", None)
        action.connect("activate", self.on_about)
        self.add_action(action)

        action = Gio.SimpleAction.new("quit", None)
        action.connect("activate", self.on_quit)
        self.add_action(action)

        for xml_name in ("cut", "copy"):
            action = Gio.SimpleAction.new(xml_name, None)
            action.connect("activate", self.on_icon)
            self.add_action(action)

    def do_activate(self):
        if not self.window:
            self.window = AppWindow(application=self, title="Main Window")
        self.window.present()

    def on_about(self, action, param):
        about_dialog = Gtk.AboutDialog(transient_for=self.window, modal=True)
        about_dialog.run()
        about_dialog.destroy()

    def on_icon(self, action, param):
        print("INFO: '%s' selected!" % action.get_name())

    def on_quit(self, action, param):
        self.quit()


if __name__ == "__main__":
    app = Application()
    app.run(sys.argv)

link di riferimento:

torna all’indice degli appunti
Gtk3 Popover

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