14 aprile, 2007

Una classe per le notifiche con python e dbus: parte seconda

Qulche tempo fa in questo post avevo spiegato come è possibile generare una notifica utilizzando python e dbus. Il commento di AS in quel post mi ha dato l'ispirazione per approfondire le conoscenze su dbus e per creare questo nuovo post con una versione più evoluta della classe python per le notifiche (vi suggerisco la lettura del post precedente prima).

La nuova bestiola mostra un esempio di come sia possibile aggiungere funzionalità alle notifiche con l'inclusione di pulsanti.

L'esempio chiarisce inoltre come sia possibile posizionare la notifica in un punto arbitrario del desktop.

Il codice python


import dbus
from dbus.mainloop.glib import DBusGMainLoop

ICON = "file:///home/redgun/python/planimo/data/icons/planimo48.png"

class Notifier:
def __init__(self):
dbus_loop = DBusGMainLoop()
self.session_bus = dbus.SessionBus(mainloop = dbus_loop)
obj = self.session_bus.get_object("org.freedesktop.Notifications",
"/org/freedesktop/Notifications")
self.notif = dbus.Interface(obj, "org.freedesktop.Notifications")

self.notif.connect_to_signal("ActionInvoked", self.action_cb)

def action_cb(self, id, act):
print act

def notify(self, title, message, iconfile = ICON, time = 3000):
hints = {}
hints['x'] = 1200
hints['y'] = 50
actions = ["a1", "Azione1", "a2", "Azione2"]
try:
self.notif.Notify("Notification",
dbus.UInt32(0), iconfile, title, message,
actions, hints, dbus.Int32(time), dbus.UInt32(0))
except:
try:
self.notif.Notify("Notification",
dbus.UInt32(0), iconfile, title, message,
actions, hints, dbus.Int32(time))
except Exception, detail:
print detail

if __name__ == "__main__":
n = Notifier()
n.notify("Title", "message <b>bold style</b>", time=10000)

import gobject
loop = gobject.MainLoop()
loop.run()


Il risultato sarà il seguente:



Da notarsi che i pulsanti sono cliccabili e le azioni possono essere gestite all'interno del metodo action_cb. La variabile hints, invece ci permette di impostare le coordinate della notifica sul desktop. Le azioni vengono specificate in una lista dove gli elementi pari rappresentano i nomi delle azioni che andranno a comparire sui pulsanti, mentre quelli dispari rappresentano il valore che verrà passato alla funzione di callback. In questo caso quindi, quando premiamo il pulsante Azione1 la funzione action_cb riceverà nella variabile act il valore a1.

7 commenti:

  1. ImportError: No module named mainloop.glib

    E' un modulo di python 2.5 (su gentoo c'è ancora la versione 2.4.4) o manca qualcosa a me?

    RispondiElimina
  2. No. mainloop fa parte di dbus. Su ubuntu il pacchetto si chiama python-dbus. Non so come si chiama su gentoo ma probabilmente avrà un nome simile

    RispondiElimina
  3. Risolto, era un problema di versione: la versione stabile è la 0.71 ma è la 0.80 che include quel modulo specifico.

    Piuttosto, qui una volta terminato il tempo la finestrella sparisce ma il loop rimane attivo. Ho notato che il programma entra nel secondo try e non nel primo.

    Infine, sarebbe carino avere un sistema per posizionare le notifiche in alto a destra indipendentemente dalla risoluzione..

    Ottimo modulo comunque!

    RispondiElimina
  4. @ tommaso

    Come avrai notato il loop viene avviato all'interno del main. Se il modulo viene integrato all'interno di una applicazione gtk non è necessario avviare il loop richiamando il metodo su gobject, ma verrà avviato direttamente dalle gtk, così che quando il loop principale delle gtk sarà terminato (ad esempio perché viene invocato il metodo gtk.main_quit()) l'applicazione terminerà normalmente.

    Il fatto che ci sono due blocchi try è solo per una questione di compatibilità con versioni precedenti.

    Per quanto riguarda il posizionamento serve un riferimento. Ad esempio se devi posizionare la notifica accanto ad una icona nella systray devi trovare un modo per capire in che posizione si trova l'icona.

    Nota inoltre che se elimini la varibile hints, passando al metodo Notify una semplice lista vuota, le notifiche appariranno sempre in basso a destra

    RispondiElimina
  5. Quello che sto capendo... è che sono ben distante dal "saper fare programmi con le gtk e pygtk" :-)
    Quindi se non riesci a darmi una mano con il problema che ti segnalavo sul post del modulo sndfile, sono in seria difficoltà.

    RispondiElimina
  6. @ tommaso

    Per qualche motivo blogger non mi ha segnalato quel commento e quindi non l'avevo visto.
    Ti ho appena risposto ;)

    RispondiElimina
  7. Anonimo9:26 PM

    Ciao! Mi piacerebbe che tu collabborassi con il nostro team Open Source che sta creando un modo per interfacciare Nokia-Linux
    (per ora siamo alla versione 0.0.4 di un piccolo script in bash) ma prossimamente siamo pronti a partire con lo sviluppo del software che sia in python o altro linguaggi C++ ecc...sei dei nostri??? per favore fatti sentire sulla mia email davidebr90@gmail.com mi sembri molto valido da quello che scrivi....e proprio ora ti ho trovato perchè ci serve una integrazione con dbus per far eseguire un comando automaticamente quando viene inserito un cell. Ciao!

    RispondiElimina