Je vais essayer d’expliquer dans cette article comment utiliser les Gtk::TreeView avec GTKmm de manière simple ! ![]()
Dans un premier temps, nous allons créer une liste simple, puis nous ajouterons, comme dans la capture au dessus, une image.
Comme à mon habitude, nous allons utiliser Glade pour dessiner l’interface graphique et créer une classe dérivé de notre fichier glade, grâce à GTKmm.
( Voire mon article précédent pour voire en détails les classes dérivé de fichiers glade )
Créer le fichier glade
Cette étape est la plus simple.
Si pour vous Glade reste quelque chose de difficile ( utiliser les Vbox et Hbox pour aligner les controls ), je vous conseil d’abord de vous entrainer à dessiner des interfaces.
Il m’y a pas vraiment de tutoriels sur Glade.. il faut pratiquer !
Donc, dans une nouvelle fenêtre placez une Vertical Box avec 2 lignes : la première pour la Gtk::TreeView, et la deuxième ligne pour un bouton quitter.
Quand vous ajouterez la Gtk::TreeView, vous aurez ceci, mais ignorez et cliquez sur Valider:
Donc, une fois fini vous devriez avoir ceci :
Donc, en résumé, nous devons lier notre classe à la fenêtre appelé wMain, puis attacher un bouton à bClose et manipuler la Gtk::TreeView tvList.
Sauvegardez votre projet glade dans un nouveau dossier, et passons au code !!
Coder notre première Gtk::TreeView
Aller mes petits, c’est l’heure de faire du C++ !!
( Ca vous manquais j’espère !!
)
Donc, vous avez créer un dossier avec votre fichier glade, nous allons y ajouter notre main.cpp ainsi que wmain.cpp et wmain.h.
Je ne ré-explique pas le fichier main.cpp ainsi que la structure de base de wmain. Voyez mon article précédent si vous avez un trou.
Bon, vous avez la fenêtre qui s’ouvre, ainsi qui se ferme avec le bouton fermer. Bien.
Nous allons paramétrer et remplir notre Gtk::TreeView !
La Gtk::TreeView fonctionne avec des Gtk::TreeModel qui représente une ligne contenant les valeurs pour chaque lignes qui sont à stocker dans un Gtk::TreeStore.
Donc il nous faut définir un Gtk::TreeModel dans lequel nous définirons le typage de chaque colonnes et nous finirons par attacher ce Gtk::TreeModel à un Gtk::TreeStore qui lui même sera attaché à notre Gtk::TreeView.
Ce qui nous permettra d’ajouter des lignes.
wmain.h avant
Je vais créer une classe qui va représenter une ligne de mon tableau, héritant de Gtk::TreeModel pour facilité l’insertion de lignes.
Jusque là, vous devriez avoir votre wmain.h comme ceci:
[sourcecode language="cpp"]
#ifndef WMAIN_H
#define WMAIN_H
#include class DerivedWMain : public Gtk::Window protected: //~——————~// private: }; #endif [/sourcecode] Ajoutons notre classe dans la classe, héritant de Gtk::TreeModel et même Gtk::TreeModel::ColumnRecord pour être précis : [sourcecode language="cpp"] #include class DerivedWMain : public Gtk::Window protected: //~——————~// //~——————~// class ModelColumns : public Gtk::TreeModel::ColumnRecord Gtk::TreeModelColumn ModelColumns modelColumns; private: }; #endif [/sourcecode] Ha oui, j’ai aussi créé ma référence à Gtk::TreeStore. Maintenant, passons au fichier cpp. Donc dans le constructeur, ajoutez ceci: [sourcecode language="cpp"] … refXmlGlade->get_widget(« tvList », gtkTreeViewList); refTreeStore = Gtk::TreeStore::create( modelColumns ); Explications: Après avoir attaché notre objet gtkTreeViewList à la list appelé tvList, il suffit de créer un pointeur de Gtk::TreeStore en instanciant et en passant en paramètre, notre classe ModelColumns. Les deux dernières lignes créer deux colonnes, et les lient avec notre classe ModelColumns. Pour ajouter une ligne, il faut créer un pointeur de Gtk::TreeModel::Row, remplir chaque champs (donc columnId et columnName) et l’ajouter au Gtk::TreeStore. [sourcecode language="cpp"] La première ligne créer une ligne vide, attaché au Gtk::TreeStore. Rien de bien difficile !! Tient ! Profitons-en pour voire les lignes dites « enfant ». Pour ajouter une ligne enfant à notre ligne fraichement créé : [sourcecode language="cpp"] C’est tout Dans la capture au tout début, vous avez put voire une icône au début. Avant tout, peut-être des idées ont jaillit dans vos tête ! La Gtk::ProgressBar, pas de problème. Il classe existe bien pour l’ajouter, vous l’avez sûrement vue dans des exemples avant de lire cet article. Tout ca pour vous faire comprendre que vous ne pouvez pas tout faire non plus. Revenons à notre icône. Ajoutons la colonne à la classe ModelColumns: [sourcecode language="cpp"] class ModelColumns : public Gtk::TreeModel::ColumnRecord Gtk::TreeModelColumn [/sourcecode] Puis, il faut créer la colonne dans le Gtk::TreeView et la lié à notre nouvelle colonne de notre classe ModelColumns. [sourcecode language="cpp"] DerivedWMain::DerivedWMain(BaseObjectType* cobject, const Glib::RefPtr … Maintenant que notre colonne existe, utilisons la. Je vous avez dis que cette colonne stockerai un pointeur de Gdk::Pixbuf, alors allons y: [sourcecode language="cpp"] Les deux ’50′ sont là pour redimensionner l’image, et le ‘true’ à la fin permet de garder les proportion de l’image. Pour vider la liste de ses lignes, il suffit d’appeler la method clear() de notre Gtk::TreeStore ! [sourcecode language="cpp"] Pour supprimer une ligne sélectionné il faut, dans un premier temps, chercher la ligne sélectionné dans le Gtk::TreeModel avec get_selected(), puis demander, comme pour vider la liste, au Gtk::TreeStore de supprimer la ligne sélectionné avec la méthode erase(). Imaginons un bouton Supprimer : [sourcecode language="cpp"] Donc le if créer un itérateur de la ligne retourné par get_selected(). Donc avec cet itérateur nous avons une référence à la ligne séléctionné. Le C++ c’est pas difficile, grâce à ces jolies bibliothèques !
#include
{
public:
DerivedWMain(BaseObjectType* cobject, const Glib::RefPtr
virtual ~DerivedWMain();
virtual void gtkButtonClose_Click();
//~ Button ~//
//~——————~//
Gtk::Button * gtkButtonClose;
Glib::RefPtrwmain.h après
#ifndef WMAIN_H
#define WMAIN_H
#include
{
public:
DerivedWMain(BaseObjectType* cobject, const Glib::RefPtr
virtual ~DerivedWMain();
virtual void gtkButtonClose_Click();
//~ Button ~//
//~——————~//
Gtk::Button * gtkButtonClose;
//~ TreeView ~//
//~——————~//
Gtk::TreeView * gtkTreeViewList;
{
public:
ModelColumns()
{
add(columnId);
add(columnName);
}
Gtk::TreeModelColumn
};
Glib::RefPtr
Glib::RefPtrLié les objets dans le constructeur
Il nous faut attacher les objets entre eux, et remplir la Gtk::TreeView.
DerivedWMain::DerivedWMain(BaseObjectType* cobject, const Glib::RefPtr
Gtk::Window(cobject),
refXmlGlade(refGlade)
{
if ( !gtkTreeViewList )
{
std::cerr << "Unable to link TreeView tvList" << std::endl;
} else {
std::cout << "TreeView tvList linked" << std::endl;
}
gtkTreeViewConfigList->set_model( refTreeStore );
gtkTreeViewConfigList->append_column( « ID », modelColumns.columnId );
gtkTreeViewConfigList->append_column( « Nom », modelColumns.columnName );
}
[/sourcecode]
Une fois Gtk::TreeStore instancié, nous devons le lié à la Gtk::TreeView avec set_model().
( Si vous vous rappelez de la boite de dialogue que vous aviez ignoré en ajoutant la Gtk::TreeView, c’est ce que cette ligne fait )Ajouter une ligne au Gtk::ListView
Gtk::TreeModel::Row row = *( refTreeStore->append() );
row[ modelColumns.columnId ] = 1;
row[ modelColumns.columnName ] = « Test »;
[/sourcecode]
Les deux suivante injecte les valeurs.![]()
Maintenant. vous devriez pouvoir créer un bouton Ajouter par exemple !Ajouter des sous lignes
En ajoutant une ligne enfant, vous aurez un ligne caché que vous pourrez afficher grâce au petit triangle devant la ligne parente.
Gtk::TreeModel::Row childOne = *( refTreeStore->append( row.children() ) );
row[ modelColumns.columnId ] = 11;
row[ modelColumns.columnName ] = « Test enfant »;
Gtk::TreeModel::Row childTwo = *( refTreeStore->append( row.children() ) );
row[ modelColumns.columnId ] = 12;
row[ modelColumns.columnName ] = « Test enfant 2″;
[/sourcecode]
Ajouter une colonne avec une image
Je vais vous expliquer comment l’ajouter.
Comme par exemple, ajouter une Gtk::ProgressBar ou encore un Gtk::Button…
Attention ! Malheureusement, il y a certaines limites. (limite de GTKmm je suppose).
Mais le Gtk::Button, quand à lui, ne peux pas être ajouté comme le Gtk::ProgressBar. Il n’existe pas de classe approprié. ( il est possible d’en ajouter … mais faut être expert en GTK!
)
Nous allons donc ajouter une colonne qui permettra d’afficher notre image.
Pour être précis, la colonne va contenir un pointeur d’un Gdk::Pixbuf.
{
public:
ModelColumns()
{
add(columnId);
add(columnName);
add(icon);
}
Gtk::TreeModelColumn
Gtk::TreeModelColumn
};
Gtk::Window(cobject),
refXmlGlade(refGlade)
{
refTreeStore = Gtk::TreeStore::create( modelColumns );
gtkTreeViewConfigList->set_model( refTreeStore );
gtkTreeViewConfigList->append_column( « Icon », modelColumns.icon );
gtkTreeViewConfigList->append_column( « ID », modelColumns.columnId );
gtkTreeViewConfigList->append_column( « Nom », modelColumns.columnName );
}
[/sourcecode]Créer une ligne avec une image
Gtk::TreeModel::Row row = *( refTreeStore->append() );
row[ modelColumns.icon ] = Gdk::Pixbuf::create_from_file(« /path/to/the/image/file.ext », 50, 50, true);
row[ modelColumns.columnId ] = 1;
row[ modelColumns.columnName ] = « Test »;
[/sourcecode]Vider la liste
Imaginons un bouton Vider :
void DerivedWMain::gtkButtonClear_Click()
{
refTreeStore->clear();
}
[/sourcecode]Supprimer une seule ligne
void DerivedWMain::gtkButtonDelete_Click()
{
//~ Check selected row
if ( const Gtk::TreeModel::iterator iter = refTreeSelection->get_selected() )
{
refTreeStore->erase(iter);
}
}
[/sourcecode]
Il suffit d’appeler erase() en passant notre itération en paramètre, et hop ! La ligne disparait !Conclusion
Maintenant j’ai hâte de voire la version 2.8 de gtkmm… Y aura des controls GTK en plus qui claque bien !!











