La boîte déroulante ComboBox
remplace le
OptionMenu
par un widget puissant qui utilise
un TreeModel
(généralement un ListStore
)
pour obtenir la liste d'éléments à afficher. Le ComboBox
applique l'interface du CellLayout
qui fournit un certain
nombre de méthodes pour gérer l'affichage des éléments de liste. Un ou plusieurs
CellRenderers
peuvent être placés dans un
ComboBox
pour personnaliser l'affichage des éléments de liste.
La manière simple de créer et remplir un ComboBox
est d'utiliser la fonction suivante :
boitederoul = gtk.combo_box_new_text()
Cette fonction crée un ComboBox
et son
ListStore
associé et le place avec un
CellRendererText
. On utilise les méthodes
suivantes pour remplir ou supprimer le contenu du ComboBox
et de son ListStore
:
boitederoul.append_text(text
) boitederoul.prepend_text(text
) boitederoul.insert_text(position
,text
) boitederoul.remove_text(position
)
... où text
est une chaîne à ajouter au
ComboBox
et position
est l'index
où le text
doit être inséré ou retiré. Dans la
plupart des cas, on n'aura besoin que de cette fonction et de ces méthodes.
Le programme d'exemple comboboxbasic.py montre l'usage des fonction et méthodes ci-dessus. La Figure 16.5, « Basic ComboBox » illustre le programme en cours :
Malheureusement, les développeurs de GTK
+ n'ont pas fourni
de méthode commode pour récupérer l'élément actif. Ceci serait pourtant
une méthode utile. Il faut créer la sienne, semblable à :
def get_active_text(boitederoul): modele = boitederoul.get_model() est_actif = boitederoul.get_active() if est_actif < 0: return None return modele[est_actif][0]
L'index de l'élément actif est récupéré par la méthode :
est_actif = boitederoul.get_active()
L'élément actif peut être défini par la méthode :
boitederoul.set_active(index
)
... où index
est un entier supérieur à -2. Si
index
vaut -1, il n'y a aucun élément actif et l'affichage
du ComboBox est vierge. Si index
est inférieur à -1,
l'appel sera ignoré. Si index
est supérieur à -1,
l'élément de liste qui possède cette valeur d'index sera affiché.
On peut se connecter au signal "changed" d'un ComboBox
pour être prévenu lorsque l'élément actif change. Le gestionnaire de "changed"
a la forme :
def fct_rappel_change(combobox, ...):
... où ...
représente zéro ou plusieurs
arguments transmis à la méthode GObject.connect
().
Créer un ComboBox
par la fonction
gtk.combo_box_new_text
() correspond à peu près
au code suivant :
liststore = gtk.ListStore(str) boitederoul = gtk.ComboBox(liststore) case = gtk.CellRendererText() boitederoul.pack_start(case, True) boitederoul.add_attribute(case, 'text', 0)
Pour utiliser les possibilités des divers objets des
TreeModel
et des
CellRenderer
, il faut créer le
ComboBox
par le constructeur :
combobox = gtk.ComboBox(model
=None)
...où model
est un TreeModel
.
Lorsque l'on crée un ComboBox
sans l'associer
à un TreeModel
, on peut ajouter celui-ci ensuite
par la méthode :
boitederoul.set_model(model
)
Le TreeModel
associé peut être
récupéré par la méthode :
modele = boitederoul.get_model()
Quelques unes des possibilités réalisables avec un
ComboBox
:
TreeModel
avec
un autre ComboBox
et
TreeView
.ComboBox
.TreeStore
ou un
ListStore
préexistant comme modèle des éléments
de liste du ComboBox
.TreeModelSort
pour
obtenir une liste classée dans le ComboBox
.
TreeModelFilter
pour utiliser
un sous-arbre d'un TreeStore
comme the source pour
les éléments de liste du ComboBox
.TreeModelFilter
pour utiliser
un sous-ensemble des lignes d'un TreeStore
ou d'un
ListStore
comme éléments de liste du
ComboBox
.L'utilisation des objets TreeModel
et
CellRenderer
objects est exposée en détail dans Chapitre 14, Le widget TreeView.
Si on a ComboBox
avec beaucoup d'éléments de liste,
ceux-ci peuvent être affichés dans une grille. Autrement, si on ne peut
afficher la liste entière, celle-ci aura des flèches de défilement. La méthode
suivante est utilisée pour fixer le nombre de colonnes à afficher ::
boitederoul.set_wrap_width(width
)
... où width
est le nombre de colonnes de la grille
affichant les éléments de liste. Par exemple, le programme
comboboxwrap.py affiche
une liste de 50 éléments sur 5 colonnes. La Figure 16.6, « ComboBox avec colonnes » illustre le programme en action :
Avec un grand nombre d'éléments, c'est à dire au-delà de 50, l'utilisation
de la méthode set_wrap_width
() fournira une faible
performance à cause du calcul de l'affichage de la grille. Pour avoir un aperçu
de l'effet, modifier la ligne 18 du programme
comboboxwrap.py pour afficher
150 éléments.
for n in range(150):
Lancer le programme pour obtenir une estimation du temps d'initialisation. Puis le modifier en commentant la ligne 17 :
#boitederoul.set_wrap_width(5)
Relancer le programme et chronométrer à nouveau. Il devrait s'exécuter beaucoup plus vite, à peu prés 20 fois plus rapidement.
Outre la méthode get_active
() décrite ci-dessus,
il est possible d'obtenir un TreeIter
désignant
la ligne active en utilisant la méthode :
iter = boitederoul.get_active_iter()
On peut aussi établir l'élément de liste actif en utilisant un
TreeIter
avec la méthode :
boitederoul.set_active_iter(iter
)
Les méthodes set_row_span_column
() et
set_column_span_column
() sont supposées permettre
la spécification du nombre de colonnes d'un TreeModel
qui contient le nombre de lignes ou de colonnes sur lesquelles les éléments de
liste doivent s'étendre dans la grille. Malheureusement, ces méthodes sont
cassées dans GTK+ 2.4.
Puisque le ComboBox
implémente l'interface
CellLayout
qui possède les mêmes capacités que
le TreeViewColumn
(voir
Section 14.5, « TreeViewColumn » pour plus d'information).
En bref, l'interface fournit :
boitederoul.pack_start(cell
,expand
=True) boitederoul.pack_end(cell
,expand
=True) boitederoul.clear()
Les deux premières méthodes place un CellRenderer
dans le ComboBox
, la méthode clear
()
supprime tous les attributs de tous les CellRenderer
.
Les méthodes suivantes :
comboboxentry.add_attribute(cell
,attribute
,column
) comboboxentry.set_attributes(cell
,...
)
... fixent les attributs pour les CellRenderer
indiqués par cell
. La méthode
add_attribute
() prend une chaîne, nom d'attibut
attribute
(par exemple 'texte') et un entier
numéro de colonne de la column
du
TreeModel
à utiliser pour placer l'attribut.
Les arguments supplémentaires de la méthode
set_attributes
() sont des paires
attribute=column
(par exemple texte=1).
Le widget ComboBoxEntry
remplace le widget
Combo
. C'est une sous-classe du widget
ComboBox
qui contient un widget fils
Entry
dont le contenu est fixé en choisissant un
élément dans une liste déroulante, en entrant directement le texte au clavier
ou par un coller depuis un presse-papier Clipboard
ou
une sélection.
Comme le ComboBox
, le ComboBoxEntry
peut être créé par la fonction :
boitderoulsaisie = gtk.combo_box_entry_new_text()
Le ComboBoxEntry
devrait être rempli en utilisant les méthodes
auxiliaires du ComboBox
décrites dans la section
Section 16.2.1.1, « Utiliser la boîte déroulante de base ».
Comme un widget ComboBoxEntry
est un widget
Bin
, son widget fils Entry
est disponible en utilisant l'attibut "child" ou la méthode
get_child
() :
saisie = boitderoulsaisie.child saisie = boitderoulsaisie.get_child()
On peut récupérer le texte de la zone Entry
par la
méthode get_text
().
Comme pour le ComboBox
, on peut surveiller les
changements de l'élément actif de la liste en se connectant au signal
"changed". Malheureusement, cela ne permet pas de suivre les modifications
de texte dans le Entry
fils lorsque ce sont des saisies
directes. Quand und saisie directe est réalisée dans le widget fils
Entry
, le signal "changed" est bien émis mais l'index retourné
par la méthode get_active
() vaudra -1. Pour surveiller
tous les changements dans le texte de la zone de saisie Entry
, il faudra
utiliser le signal "changed" du widget Entry
. Par exemple :
def fct_rappel_change(saisie): print saisie.get_text() boitderoulsaisie.child.connect('changed', fct_rappel_change)
... affichera le texte après chaque modification dans le widget fils
Entry
. Pour exemple, le programme
comboboxentrybasic.py
montre l'utilisation de l'API. La figure Figure 16.7, « Liste déroulante avec zone de saisie »
illustre le programme en action.
Il faut noter que lorsque le texte du Entry
est modifié
par un choix dans la liste déroulante, le gestionnaire du signal "changed" est
appelé deux fois :une fois quand le texte est supprimé et une autre fois
quand le texte prend la valeur du texte de l'élément de liste choisi.
Le constructeur du ComboBoxEntry est :
boitderoulsaisie = gtk.ComboBoxEntry(model
=None,column
=-1)
... où model
est un TreeModel
et column
est le numéro de la colonne du
model
à utiliser pour créer la liste d'éléments.
Si la colonne n'est pas précisée, la valeur par défaut est -1,
ce qui signifie que la colonne du texte n'est pas indiquée.
Créer un ComboBoxEntry
avec la fonction
auxiliaire gtk.combo_box_entry_new_text
() est équivalent
à :
liststore = gtk.ListStore(str) boitderoulsaisie = gtk.ComboBoxEntry(liststore, 0)
Le ComboBoxEntry
ajoute quelques méthodes utilisées
pour fixer et récupérer le numéro de colonne du
TreeModel
à utiliser pour fixer les chaînes des éléments
de liste :
boitderoulsaisie.set_text_column(text_column
)
text_column = boitderoulsaisie.get_text_column()
La colonne du texte peut aussi être récupérée et fixée en utilisant la
propriété "text-column". Se reporter à la section Section 16.2.1.2, « Usage avancé de ComboBox » pour plus de renseignements sur l'utilisation avancée du
ComboBoxEntry
.
Votre application doit indiquer la colonne de texte pour que le
ComboBoxEntry
établisse le contenu
de la zone Entry
depuis la liste déroulante.
la colonne de texte ne peut être indiqué qu'une fois, soit en utilisant le
constructeur, soit en utilisant la méthode set_text_column
().
Lorqu'on crée un ComboBoxEntry
, il est placé avec un
nouveau CellRendererText
qui n'est pas accessible. L'
attribut 'text' du CellRendererText
doit être fixé, c'est un
effet secondaire de l'utilisation de la méthode set_text_column
()
pour déterminer la colonne de texte. On peut placer des CellRenderer
supplémentaires dans un ComboBoxEntry
pour l'affichage dans la
liste déroulante. Se reporter à la section Section 16.2.1.2, « Usage avancé de ComboBox »
pour plus d'information.