Le widget gtk.Calendar est un moyen efficace pour afficher et récupérer des informations calendaires organisées par mois. Il s'agit d'un widget très simple à créer et à utiliser.
Pour créer un calendrier, il suffit d'utiliser la méthode suivante :
calendrier = gtk.Calendar()
Par défaut, le calendrier affiche le mois et l'année courants.
On pourra parfois avoir besoin de modifier plusieurs données de ce widget ; les méthodes qui suivent permettront d'apporter un grand nombre de modifications au calendrier, ceci sans que l'utilisateur n'ait à voir son affichage s'actualiser à chacune d'elles.
calendrier.freeze() calendrier.thaw()
Le fonctionnement est exactement le même que pour les méthodes de gel (freeze) et de dégel (thaw) de tout autre widget.
Le calendrier dispose de quelques options permettant de changer son aspect et son comportement. On y accède par l'intermédiaire de la méthode suivante :
calendrier.display_options(flags)
L'argument flags (drapeaux) peut comporter n'importe lesquelles des cinq options suivantes, combinées le cas échéant avec l'opérateur de manipulation de bits OR (|) :
CALENDAR_SHOW_HEADING | Cette option spécifie que le mois et l'année doivent apparaitre dans l'affichage du calendrier. |
CALENDAR_SHOW_DAY_NAMES | Cette option spécifie que des désignations à trois lettres doivent être affichées pour chaque jour (lun, mar, etc.). |
CALENDAR_NO_MONTH_CHANGE | Cette option spécifie que l'utilisateur ne doit pas pouvoir afficher d'autre mois que celui qui est affiché. Cela peut être utile lorsque on ne souhaite afficher qu'un seul mois précis, par exemple dans le cas où l'on affiche 12 calendriers, un pour chaque mois d'une année donnée. |
CALENDAR_SHOW_WEEK_NUMBERS | Cette option spécifie que le numéro de chaque semaine doit être affiché sur la gauche du calendrier (1er Jan = Semaine 1, 31 Déc = Semaine 52). |
CALENDAR_WEEK_START_MONDAY | Cette option spécifie que la semaine du calendrier commence le lundi, et non pas le dimanche (réglage par défaut). Seul est affecté l'ordre dans lequel sont affichés les jours de gauche à droite. |
On utilise les méthodes suivantes pour définir la date affichée :
resultat = calendrier.select_month(month, year) calendrier.select_day(day)
La méthode select_month() renvoie une valeur booléenne indiquant si la sélection s'est déroulée avec succès.
Avec la méthode select_day(), le numéro de jour spécifié se voit sélectionné dans le mois courant, dans la mesure du possible. Un numéro de jour de 0 aura pour effet d'invalider toute sélection courante.
Outre le fait qu'un jour du mois puisse être sélectionné, chacun des autres jours peut être "marqué", c'est-à-dire mis en relief dans l'affichage du calendrier. On se servira des méthodes suivantes pour manipuler les jours marqués :
resultat = calendrier.mark_day(day) # marquer un jour resultat = calendrier.unmark_day(day) # démarquer un jour calendrier.clear_marks() # enlever toutes les marques
mark_day() et unmark_day() renvoient une valeur booléenne indiquant si l'opération s'est déroulée avec succès. Notez que les marques sont conservées même lors de changements de mois ou d'année.
La dernière méthode du calendrier permet de récupérer la date, le mois et l'année sélectionnés.
année, mois, jour = calendrier.get_date()
Le widget gtk.Calendar peut générer un certain nombre de signaux indiquant un changement ou une sélection de date. En voici une liste :
month_changed # mois changé day_selected # jour selectionné day_selected_double_click # jour selectionné double-clic prev_month # mois précédent next_month # mois suivant prev_year # année précédente next_year # année suivante
Il ne nous reste plus qu'à rassembler tout ceci dans le programme exemple calendrier.py. La Figure 9.12 montre le résultat du programme :
Voici le code source de calendrier.py :
1 #!/usr/bin/env python 2 3 # exemple calendrier.py 4 # 5 # Copyright (C) 1998 Cesar Miquel, Shawn T. Amundson, Mattias Gronlund 6 # Copyright (C) 2000 Tony Gale 7 # Copyright (C) 2001-2002 John Finlay 8 # 9 # This program is free software; you can redistribute it and/or modify 10 # it under the terms of the GNU General Public License as published by 11 # the Free Software Foundation; either version 2 of the License, or 12 # (at your option) any later version. 13 # 14 # This program is distributed in the hope that it will be useful, 15 # but WITHOUT ANY WARRANTY; without even the implied warranty of 16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 # GNU General Public License for more details. 18 # 19 # You should have received a copy of the GNU General Public License 20 # along with this program; if not, write to the Free Software 21 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 22 23 import pygtk 24 pygtk.require('2.0') 25 import gtk, pango 26 import time 27 28 class ExempleCalendrier: 29 DEF_ESP = 10 30 DEF_PETIT_ESP = 5 31 ANNEE_BASE = 1900 32 33 calendrier_affich_entete = 0 34 calendrier_affich_jours = 1 35 calendrier_change_mois = 2 36 calendrier_affich_semaine = 3 37 38 def calendrier_date_chaine(self): 39 annee, mois, jour = self.fenetre.get_date() 40 date = time.mktime((annee, mois+1, jour, 0, 0, 0, 0, 0, -1)) 41 return time.strftime("%x", time.localtime(date)) 42 43 def calendrier_chaines_signaux(self, chaine_signal): 44 penult_sig = self.penult_sig.get() 45 self.apenult_sig.set_text(penult_sig) 46 47 penult_sig = self.dern_sig.get() 48 self.penult_sig.set_text(penult_sig) 49 self.dern_sig.set_text(chaine_signal) 50 51 def calendrier_change_mois(self, widget): 52 tampon = "month_changed : %s" % self.calendrier_date_chaine() 53 self.calendrier_chaines_signaux(tampon) 54 55 def calendrier_selec_jour(self, widget): 56 tampon = "day_selected : %s" % self.calendrier_date_chaine() 57 self.calendrier_chaines_signaux(tampon) 58 59 def calendrier_selec_jour_dbleclic(self, widget): 60 tampon = "day_selected_double_click : %s" 61 tampon = tampon % self.calendrier_date_chaine() 62 self.calendrier_chaines_signaux(tampon) 63 64 annee, mois, jour = self.fenetre.get_date() 65 66 if self.date_marquee[jour-1] == 0: 67 self.fenetre.mark_day(jour) 68 self.date_marquee[jour-1] = 1 69 else: 70 self.fenetre.unmark_day(jour) 71 self.date_marquee[jour-1] = 0 72 73 def calendrier_mois_prec(self, widget): 74 tampon = "prev_month : %s" % self.calendrier_date_chaine() 75 self.calendrier_chaines_signaux(tampon) 76 77 def calendrier_mois_suiv(self, widget): 78 tampon = "next_month : %s" % self.calendrier_date_chaine() 79 self.calendrier_chaines_signaux(tampon) 80 81 def calendrier_annee_prec(self, widget): 82 tampon = "prev_year : %s" % self.calendrier_date_chaine() 83 self.calendrier_chaines_signaux(tampon) 84 85 def calendrier_annee_suiv(self, widget): 86 tampon = "next_year : %s" % self.calendrier_date_chaine() 87 self.calendrier_chaines_signaux(tampon) 88 89 def calendrier_def_drapeaux(self): 90 options = 0 91 for i in range(5): 92 if self.reglages[i]: 93 options = options + (1<