erlug
[Top] [All Lists]

Re: [Erlug] menu per applet (Python + Gtk)

To: erlug@xxxxxxxxxxxxxx
Subject: Re: [Erlug] menu per applet (Python + Gtk)
From: Davide Alberani <da@xxxxxxxxxxxxxx>
Date: Tue, 15 Sep 2009 20:15:52 +0200
On Sep 04, Davide Alberani <da@xxxxxxxxxxxxxx> wrote:

Non pretendo mica i _programmi_, ma GIURO che chi non documenta a
decenza le proprie _librerie_, SARÀ IL PRIMO AD ESSERE MESSO
AL MURO QUANDO CI SARÀ LA MIA RIVOLUZIONE.  E che cavoli...
Devo riguardarmi "La Caduta", in tv, stasera.  E prendere appunti. <g>

Mi auto-rispondo giusto per lasciare da qualche parte gli ulteriori
cancheri tirati a chi non crede allo scrivere documentazione (e
di ottenere aiuto via IRC o mailing list, neanche a parlarne - soccia,
sui canali di gimpnet lo sport preferito erano scambi di "PING" e
"PONG": neanche alle elementari..)

> C'è un posto speciale, all'inferno, riservato a chi non ha fatto
> nulla per semplificare il debugging di applet Gnome, me lo sento...

Questo si può fare così, eseguendo l'applet in una normale finestra:
  window = gtk.Window(gtk.WINDOW_TOPLEVEL)
  window.set_size_request(200, 200)
  applet = gnomeapplet.Applet()
  # QUI AGGIUNGI I WIDGET DEI TUOI SOGNI AD applet
  applet.reparent(window)
  window.show_all()
  gtk.main()
  
> - una manciata di "radio button" dinamici (non che quelli statici mi
>   funzionino, al momento).

L'XML accettato da applet.setup_menu PARE essere un sottoinsieme non
documentato di quello di Bonobo UI.  Ergo, 'commands' e 'cmd' sono
_internamente_ utilizzati, ma bellamente ignorati se li scrivete
nell'XML.  Puro genio.
Rincariamo dicendo che per i normali 'menuitem' l'attributo 'verb'
va associato ad una callback passata come lista di tuple di due
elementi ('verb', callBack) nel secondo parametro di applet.setup_menu,
mentre per i radio Button-campione-del-mondo dovete aggiungere un
listener all'istanza bonobo.ui.Component che rappresenta effettivamente
il vostro menu.  Ho bisogno di un paio di pinze per spiegare agli autori
il concetto di 'intuitivo'.

Ergo (verb="" assegna il 'verb' identico al 'name' - OLÈ, NANI E BALLERINE!):
XML = """
<popup name="button3">
  <menuitem name="baa" verb="" label="baa" />
  <menuitem name="baa2" verb="" label="baa2" />
  <separator />
  <menuitem type="radio" group="gruppo" name="radio1" verb="" label="radio1" />
  <menuitem type="radio" group="gruppo" name="radio2" verb="" label="radio2" />
</popup>
"""

Si attiva così, per i normali 'menuitem':
  applet.setup_menu(menuXML, [('baa', cbForBaa), ('baa2', cbForBaa2)], None)

Mentre per i radio button:
  menu = applet.get_popup_component()
  menu.add_listener('radio1', callBackForRadio1)
  menu.add_listener('radio2', callBackForRadio2)

Solo ora (visto che farlo nell'xml pare essere un esercizio futile) si
possono settare le proprietà che sarebbero da mettere nei tag 'cmd'; e.g.:
  menu.set_prop('/commands/radio2', 'state', '1')
  menu.set_prop('/commands/baa', 'sensitive', '0')

Ah già, dimenticavo che a me interessava un menu dinamico, con parte
del contenuto aggiunto/rimosso al volo.
Non sta scritto in nessun dove, ma chiamare applet.setup_menu con un
nuovo XML fa un po' di malippo: le entry (univocamente identificate
con 'name' o 'id') che già erano presenti continueranno ad esistere (a
prescindere dal fatto che le abbiate segate nel nuovo XML), mentre
quelle nuove verranno sempre e comunque aggiunte in fondo al menu.

Per vivere felici, prima di ricreare il menu, basta dare un giro di:
  menu = applet.get_popup_component()
  menu.rm('/')  # rm!  Come sono sagaci!

Per ora non mi pare ci siano controindicazioni, ma nel caso fosse
necessario segare le callback ed i listener definiti:
  if menu.path_exists('/commands/%s' % verb):
      menu.rm('/commands/%s' % verb) # superfluo, ad onor del vero.
      menu.remove_verb(verb)
  if menu.path_exists('/commands/%s' % listener):
      menu.remove_listener(listener)

Dove 'verb' e 'listener' sono le stringe 'verb' dell'xml.
Oh, che mi venga un colpo se son riuscito a farmi restituire un
elenco di callback e di listener associate ad un menu (ovvero:
li dovete sapere voi...)

Le funzioni di callback per i semplici menu item (se assegnati usando
"None" come terzo parametro di setup_menu), vengono chiamate con
il widget e - mi pare - il valore di 'verb' come parametri (ma 'sta
parte è documentata in giro, stranamente).
Le funzioni associate ai listener ricevono in dono il widget, il verb
(o forse 'id' e/o 'name'), un parametro misterioso (0 - rappresenta
la proprietà che lo attiva?  Non ricordo - lo avevo visto in qualche
sorgente C, ma non ho voglia di cercarlo) ed un valore che per i
radio button può essere 0 se deselezionato o 1 se selezionato.
Sì, vi serve perché gtk+, nel cambiare selezione su un gruppo di radio
button, emette _due_ segnali: uno per il vecchio (0) ed uno per
il nuovo (1).


Ora filate tutti a scrivere documentazione o vengo lì a sculacciarvi
con una mazza chiodata arrugginita!

-- 
Davide Alberani <da@xxxxxxxxxxxxxx> [GPG KeyID: 0x465BFD47]
http://erlug.linux.it/~da/

<Prev in Thread] Current Thread [Next in Thread>