The Model/View/Controller design (Python) Le concept Modèle/Vue/Contrôleur Sebastian Pölsterl sebp@k-d-w.org 2011 Marta Maria Casetti mmcasetti@gmail.com 2012 Luc Rebert, traduc@rebert.name 2011 Alain Lojewski, allomervan@gmail.com 2011-2012 Luc Pionchon pionchon.luc@gmail.com 2011 Bruno Brouard annoa.b@gmail.com 2011-12 Luis Menina liberforce@freeside.fr 2014 Le concept Modèle/Vue/Contrôleur
Présentation

Les deux éléments graphiques TreeView et BoiteCombinee sont construits sur le concept Modèle/Vue/Contrôleur. Le Modèle (une implémentation de Gtk.TreeModel, habituellemnt soit Gtk.TreeStore, soit Gtk.ListStore) stocke les données ; laVue (par ex. Gtk.TreeView, Gtk.ComboBox, ou Gtk.ComboBoxText) obtient les notifications de modifications et affiche le contenu du modèle. Enfin, le Contrôleur modifie l'état du modèle (à l'aide de méthodes dans l'implémentation du modèle, comme append(), ou remove()) et indique à la Vue ces modifications (à l'aide de signaux comme "changed").

Le Modèle

La principale différence entre les deux implémentations principales de Gtk.TreeModel est que Gtk.ListStore ne contient que des lignes de données sans enfant, alors que Gtk.TreeStore contient aussi des lignes de données mais que chacune d'elle peut contenir des lignes enfants (qui à leur tour peuvent aussi contenir des lignes enfants et ainsi de suite).

Les données du modèle peuvent être supprimées ou modifiées avec l'itérateur arborescent et l'indexe de la colonne, ou avec Gtk.TreeIter, ou Gtk.TreePath.

Comme avec l'objet liste intégré dans Python, vous pouvez obtenir le nombre de lignes avec len() et utiliser des segments pour récupérer ou définir des valeurs. D'une autre façon, la méthode append() renvoie un exemple de Gtk.TreeIter qui pointe vers l'emplacement de la ligne qui vient d'être insérée. L'appel à la fonction get_iter() récupère aussi un Gtk.TreeIter.

Comme Gtk.ListStore n'a qu'un seul niveau, c-à-d. les nœuds n'ont aucun nœud enfant, un chemin est essentiellement représenté par l'index de la ligne à laquelle vous souhaitez accéder. En ce qui concerne Gtk.TreeStore, un chemin est représenté par une liste d'indexes ou une chaîne de caractères. La chaîne se présente sous la forme d'une liste de nombres séparés par une colonne. Chaque nombre se réfère au décalage à ce niveau. Donc, le chemin "0" se réfère au nœud racine et le chemin "2:4" se réfère au cinquième enfant du troisième nœud.

Méthodes utiles pour un Gtk.TreeModel :

La méthode get_iter(chemin) renvoie un exemple de Gtk.TreeIter qui pointe vers le chemin. Ce chemin est soit une liste de nombres séparés par une colonne, soit un tuple. Par exemple, la chaîne de caractères "10:4:0" est équivalente au tuple (10, 4, 0), car tous deux créent un chemin de niveau 3 pointant vers le 11ème enfant du nœud racine, le 5ème enfant de cet 11ème enfant et le 1er enfant de ce 5ème enfant.

La méthode iter_next(TreeIter) renvoie un exemple de Gtk.TreeIter qui pointe vers le nœud TreeIter suivant situé au même niveau, ou vers None s'il n'y a rien derrière.

La méthode iter_has_child(TreeIter) renvoie la valeur vrai si TreeIter a des enfants, ou faux dans le cas contraire.

La méthode iter_children(TreeIter) renvoie un exemple de Gtk.TreeIter qui pointe vers le premier enfant de TreeIter, ou sur None si TreeIter n'a pas d'enfant.

La fonction get_iter_first() renvoie un exemple de Gtk.TreeIter qui pointe vers le premier itérateur arborescent (celui du chemin "0") ou sur None si l'arborescence est vide.

Méthodes utiles pour un Gtk.ListStore :

La méthode append(ligne) ajoute une nouvelle ligne à ce magasin liste, où ligne peut être une liste de valeurs pour chaque colonne ; ligne peut aussi être omis ou avoir la valeur None et dans ces cas une colonne vide est ajoutée. La méthode renvoie un Gtk.TreeIter qui pointe vers la ligne ajoutée.

La méthode remove(iter) supprime l'iter du magasin Gtk.ListStore et renvoie la valeur vrai si l'itérateur est valide ou faux dans le cas contraire. Après sa suppression, l'iter est configuré pour devenir la prochaine ligne valide.

Méthodes utiles pour un Gtk.TreeStore :

La méthode append(parent, ligne) ajoute une nouvelle ligne à ce magasin arborescent ; parent doit être un Gtk.TreeIter valide. Si la valeur du parent est différente de None, alors elle ajoute la nouvelle ligne après le dernier enfant du parent, sinon elle ajoute une ligne au premier niveau ; ligne peut être une liste de valeurs pour chaque colonne, ou alors peut être omis ou avoir la valeur None ; dans ce dernier cas, une colonne vide est ajoutée. La méthode renvoie un Gtk.TreeIter qui pointe vers la ligne ajoutée.

La méthode remove(iter) supprime l'iter du magasin Gtk.ListStore et renvoie la valeur vrai si l'itérateur est valide ou faux dans le cas contraire. Après sa suppression, l'iter est configuré pour devenir la prochaine ligne valide.

La Vue : le cas de la TreeView

Une TreeView affiche la structure des éléments enfants et parents sous la forme des branches d'un arbre. Regardez cet exemple.

La Gtk.TreeViewColumn est utilisée pour organiser les colonnes verticales.

Méthodes utiles pour une vue Gtk.TreeView :

La méthode set_model(modele) définit le modèle de cette vue arborescente. Si elle a déjà un modèle défini, la fonction le supprime avant de lui définir le nouveau. Si la valeur du modèle est None, la fonction supprime l'ancien modèle.

La méthode get_model() renvoie le modèle sur lequel est construite cette vue arborescente, ou None si le modèle n'est pas défini.

La méthode append_column(colonne) ajoute colonne à la liste de colonnes.

La méthode get_selection() récupère la sélection Gtk.TreeSelection associée à cette vue arborescente.

Méthodes utiles pour une Gtk.TreeViewColumn :

La méthode add_attribute(renderer, attribut, valeur) ajoute un mappage d'attribut à cette colonne. attribut est le paramètre du renderer à définir à partir de la valeur valeur

La méthode pack_start(renderer, expand) compresse le renderer au début de cette colonne. Si la valeur d'expand est False, alors il est alloué au renderer juste l'espace qui lui est nécessaire. Tout espace inutilisé est divisé à parts égales entre les cellules pour lesquelles la valeur est True.

La méthode pack_end(renderer, expand) compresse le renderer à la fin de cette colonne. Si la valeur d'expand est False, alors il est alloué au renderer juste l'espace qui lui est nécessaire. Tout espace inutilisé est divisé à parts égales entre les cellules pour lesquelles la valeur est True.

set_sort_column_id(sort_column_id) sets the column of the model by which this column (of the view) should be sorted. This also makes the column header clickable.

La méthode set_sort_indicator(setting) définit s'il faut afficher une petite flèche dans l'en-tête de la colonne ; le setting possible peut être soit True (la flèche est visible), soit False.

La méthode set_sort_order(ordre) modifie l'ordre de tri de la colonne ; l'ordre peut être soit Gtk.SortType.ASCENDING, soit Gtk.SortType.DESCENDING.

La Vue : cas de l'élément graphique BoiteCombinee

Une Gtk.ComboBox permet de sélectionner un élément à partir d'un menu déroulant, regardez cet exemple. Pour une liste de choix textuels, on peut aussi utiliser plus simplement un Gtk.ComboBoxText. Les deux peuvent contenir une entrée.

Méthodes utiles pour un élément graphique Gtk.ComboBox :

La méthode statique new_with_entry() crée une nouvelle BoiteCombinee Gtk.ComboBox avec une entrée ; la méthode statique new_with_model(model) en crée une nouvelle à partir du modèle initialisé à model ; et la méthode statique new_with_model_and_entry(model) est une combinaison des deux autres.

La méthode get_active_iter() renvoie un Gtk.TreeIter qui pointe vers l'élément actif actuel. S'il n'y en a pas, elle renvoie None.

La méthode set_model(model) définit le modèle utilisé par la boîte combinée à model et annule le modèle précédent s'il existait déjà. Si la valeur model est None, alors la fonction annule le paramétrage du modèle. Notez que cette fonction ne supprime pas les générateurs de rendu de cellules.

La méthode set_entry_text_column(text_column) définit la colonne du modèle que cette boîte combinée doit utiliser pour que ses chaînes de caractères soient du type text_column. La colonne text_column dans ce modèle de boîte combinée doit être du type str (ceci n'est pertinent que si cette boîte combinée a été créée avec la propriété « has-entry » définie à True).

set_wrap_width(width) sets the wrap width of this combo box to be width. The wrap width is basically the preferred number of columns when you want the popup to be laid out in a grid.

Méthodes utiles pour une boîte Gtk.ComboBoxText :

La méthode statique new_with_entry() crée une nouvelle Gtk.ComboBoxText vide avec une entrée.

La méthode append_text(texte) ajoute le texte à la liste des chaînes stockées dans cette boîte combinée.

La méthode get_active_text() renvoie la chaîne active actuelle de cette boîte combinée, ou None si aucune chaîne n'est sélectionnée. Si la boîte combinée contient une entrée, la méthode renvoie son contenu (qui n'est pas nécessairement un élément de la liste).

La Vue : les Cellrenderers

La Vue se sert de Gtk.CellRenderer de différents types pour dessiner les données.

Implémentations de Gtk.CellRenderer et méthodes utiles :

Gtk.CellRendererText - génère du texte dans une cellule

Gtk.CellRendererToggle - génère un bouton de basculement ou de radio dans une cellule. Méthodes utiles :

set_active(setting) - active ou désactive un générateur de rendu

get_active() - indique si le générateur de rendu est actif

set_radio(radio) - si la valeur radio est True, le générateur crée un bouton de radio inverseur (par ex. un inverseur d'un groupe mutuellement exclusif) ; si la valeur est False, il génère un inverseur de vérification (une option boléenne autonome)

get_radio() - indique si nous générons des boutons de basculement au lieu de cases à cocher.

Gtk.CellRendererPixbuf - génère un rendu image dans une cellule

Gtk.CellRendererCombo - génère un rendu texte dans une cellule ; mais, alors que Gtk.CellRendererText n'offre qu'une simple entrée pour modifier le texte, Gtk.CellRendererCombo offre un élément graphique Gtk.ComboBox pour la même action. Il peut être utilisé avec ou sans un élément graphique Gtk.Entry associé, en fonction de la propriété de la valeur « has-entry ».

Gtk.CellRendererProgress - génère une valeur numérique sous forme de barre de progression dans une cellule ; il peut afficher du texte au-dessus de la barre de progression

Gtk.CellRendererSpinner - génère l'animation d'un indicateur dans une cellule

Gtk.CellRendererSpin - génère un bouton d'activité dans une cellule

Gtk.CellRendererAccel - génère un accélérateur de clavier dans une cellule

Le contrôleur : la sélection

La plupart des applications doivent non seulement afficher des données, mais aussi réceptionner les événements émis par les utilisateurs. Pour faire cela, il faut tout simplement obtenir une référence pour un objet sélectionné et la connecter au signal « changed ».

select = tree.get_selection() select.connect("changed", on_tree_selection_changed)

Ensuite, pour récupérer les données pour la colonne sélectionnée :

def on_tree_selection_changed(selection): model, treeiter = selection.get_selected() if treeiter != None: print "You selected", model[treeiter][0]

Useful methods for a Gtk.TreeSelection:

La méthode set_mode(type) définit le type de sélection, où type est l'un des

Gtk.SelectionMode.NONE - pas de sélection possible

Gtk.SelectionMode.SINGLE - zéro ou un élément peut être sélectionné

Gtk.SelectionMode.BROWSE - exactement un élément est sélectionné. Dans certaines circonstances, comme au début ou pendant une opération de recherche, il est possible qu'il n'y ait aucun élément pouvant être sélectionné. Ce qui est réellement imposé, c'est l'impossibilité pour l'utilisateur de désélectionner un élément actuellement sélectionné sauf s'il en sélectionne un autre.

Gtk.SelectionMode.MULTIPLE -any number of elements may be selected. Clicks toggle the state of an item. The Ctrl key may be used to enlarge the selection, and Shift key to select between the focus and the child pointed to. Some widgets may also allow Click-drag to select a range of elements.

La méthode get_selected() renvoie un tuple (modele, TreeIter), où modele est le modèle actuel et TreeIter un Gtk.TreeIter qui pointe soit vers la ligne actuellement sélectionnée, soit vers None si aucune ligne n'est sélectionnée. La méthode ne marche pas si le type de sélection est défini à Gtk.SelectionMode.MULTIPLE ; dans ce cas, utilisez à la place la fonction get_selected_rows(), qui renvoie une liste d'exemples Gtk.TreePath de toutes les lignes sélectionnées.

Références

GtkTreeModel

GtkTreeView

GtkTreeViewColumn

GtkComboBox

GtkCellRenderer