#!⌨

Tutoriel : créer une notification en Python

Une fonctionnalité d'un de mes projets consiste à notifier un utilisateur directement sur son bureau (et pas dans son navigateur). J'ai décidé dans un premier temps de faire un prototype pour mon bureau Gnome Shell. Cette technique devrait toutefois être possible pour la plupart des environnements de bureau sous Linux.

Pour réaliser cette fonctionnalité, c'est plutôt simple mais peu documenté. Il suffit d'utiliser la libnotify qui implémenterais une specification FreeDesktop (je n'ai toutefois pas retrouvé la spécification sur le site de FreeDesktop, seulement ce document chez Gnome).

Afin d'utiliser la libnotify sous Python, il faut passer par le package pygobject qui fournit les bindings aux librairies Gnome. Pour installer pygobject, il semblerait qu'on ne puisse pas passer par distribute et pip. Il faut donc installer le package de sa distribution. Pour mon Arch Linux, la commande est donc : pacman -S python2-gobject.

Ensuite, créer une notification est simple :

from gi.repository import Notify
# initialisation de libnotify avec le nom de notre application
Notify.init('example')
# création de la notification
notif = Notify.Notification.new(
  'Title', # titre
  'Longer message', # message
  'dialog-information' # icône
)
# affichage
notif.show()

En exécutant ce code, une notification devrait apparaitre. Elle affiche simplement notre message, sans faire aucune action :

Notification affichée

La notification affichée

Pour effectuer une action lors du clic sur la notification, il suffit alors de rajouter une fonction callback sur l'évènement closed de la notification :

from gi.repository import Notify
from gi.repository import Gtk

Notify.init('example')
notif = Notify.Notification.new(
    'Title', # titre
    'Longer message', # message
    'dialog-information' # icône
)

# définition de notre callback
# un seul argument : l'objet notification
def callback(notif_object):
    # on peut faire des choses ici
    Gtk.main_quit()

# enregistrement de notre callback sur le signal closed
notif.connect('closed', callback)
notif.show()
Gtk.main()

On notera cette fois l'appel à des fonctions gtk : on doit maintenir notre programme en vie jusqu'à ce que le signal closed soit lancé afin de pouvoir exécuter notre callback.

On peut également ajouter un bouton avec une action à lancer lors du clic :

from gi.repository import Notify
from gi.repository import Gtk

Notify.init('example')
notif = Notify.Notification.new(
    'Title', # titre
    'Longer message', # message
    'dialog-information' # icône
)

# définition de la callback exécutée lors du clic sur le bouton
def callback(notif_object, action_name, users_data):
    # on peut faire des choses ici
    notif_object.close()
    Gtk.main_quit()

# ajout de notre action sur la notification
notif.add_action(
    'our_callback', # identifiant
    'Callback and quit', # texte du bouton
    callback, # function callback de notre bouton
    None, # user_datas, ce dont vous avez besoin dans la callback
    None # fonction qui supprime les user_datas
)
notif.show()
Gtk.main()

À l'affichage de notre notification, on voit maintenant un bouton en dessous du message. Lorsqu'on clique dessus, notre callback sera exécutée. Ici, nous fermons la notification et mettons fin à la boucle de Gtk.

Notification affichée avec un bouton actionable

La notification affichée avec un bouton actionable

On voit que la signature de notre fonction callback a changé par rapport à la callback liée au signal. On peut toutefois combiner les deux : une callback sur le signal closed et une sur le clic sur le bouton.

D'autres fonctionnalités sont accessibles, on peut les retrouver dans la documentation de libnotify. La documentation de PyGObject peut également s'avérer utile dans vos développements.