Tuve la suerte de entrar a #gnome en irc.cl cuando jci se encontraba programando o al menos, con dudas respecto de programación en GTK+. Un oasis a decir verdad, ya que en el último tiempo el canal se había desvirtuado bastante de su origen, con preguntas de Linux en general o cualquier tipo de conversación, lo cual no está mal, pero no es muy atractivo que digamos.
Así fue que la duda radicaba en la forma de unir en una misma columna una imagen y un texto, esto es, usando GtkTreeView con GTK+ 2.x. Así que me dí un tiempo y programé un pequeño ejemplo que muestra como implementarlo. El ejemplo se limita sólo a mostrar esta funcionalidad.
La salida del programa de ejemplo, se aprecia en la siguiente captura:

Y el código que lo genera es el que se muestra a continuación:
/* treeview.c: Ejemplo de uso de GtkTreeView para unir pixbuf y
* texto en una misma columna.
*
* (c) 2003. German Poo Caaman~o
*
* Compilacion:
* $ gcc `pkg-config --cflags --libs gtk+-2.0` -Wall treeview.c -o treeview
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <gtk/gtk.h>
GtkWidget *create_window ();
static GtkTreeModel *create_model ();
static void add_columns (GtkTreeView * treeview);
const char *rightarrow_xpm[] = {
"20 16 27 1",
" c None",
". c #000000",
"+ c #00FFFF",
"@ c #00E7E7",
"# c #00F5F5",
"$ c #00C4C4",
"% c #009595",
"& c #00FDFD",
"* c #00F9F9",
"= c #00CCCC",
"- c #00A2A2",
"; c #00EFEF",
"> c #00C7C7",
", c #00A8A8",
"' c #00DDDD",
") c #00A4A4",
"! c #009696",
"~ c #008E8E",
"{ c #008F8F",
"] c #00A5A5",
"^ c #00C3C3",
"/ c #007878",
"( c #009E9E",
"_ c #007777",
": c #00A7A7",
"< c #006969",
"[ c #007676",
" ",
" ",
" .. ",
" .+. ",
" .+@. ",
" ...........#$%. ",
" .&*+++++++#=$=-. ",
" .;>=======$$==,,.",
" .')!~~~~~{]^=~/. ",
" ...........({_. ",
" .:<. ",
" .[. ",
" .. ",
" ",
" ",
" "
};
const char *leftarrow_xpm[] = {
"20 16 29 1",
" c None",
". c #000000",
"+ c #EE0000",
"@ c #D90000",
"# c #CE0000",
"$ c #C00000",
"% c #EA0000",
"& c #D70000",
"* c #C60000",
"= c #C10000",
"- c #FF0000",
"; c #F40000",
"> c #C40000",
", c #CF0000",
"' c #BE0000",
") c #C30000",
"! c #CD0000",
"~ c #C50000",
"{ c #CC0000",
"] c #AA0000",
"^ c #BC0000",
"/ c #B50000",
"( c #AC0000",
"_ c #A70000",
": c #8E0000",
"< c #B20000",
"[ c #9A0000",
"} c #A20000",
"| c #930000",
" ",
" ",
" .. ",
" .+. ",
" .+@. ",
" .+#$........... ",
" .%&*=@-------;>. ",
".+,'=)!~{{{{{{*]. ",
" .]$^/(_]]]]]]]:. ",
" .]<[........... ",
" .}|. ",
" .:. ",
" .. ",
" ",
" ",
" "
};
int
main (int argc, char *argv[])
{
GtkWidget *window;
gtk_init (&argc, &argv);
window = create_window ();
gtk_widget_show_all (window);
gtk_main ();
return 0;
}
/* Creacion de la UI principal, es basica: consta de una ventana,
un contenedor de desplazamiento (scrolledwindow) y un GtkTreeView
dentro del contenedor. Solo respondemos a la sen~al 'delete-event',
que indica que la aplicacion termina.
*/
GtkWidget *
create_window ()
{
GtkWidget *window;
GtkWidget *scrolledwindow;
GtkWidget *treeview;
GtkTreeModel *model;
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (window), "GtkTreeView sample");
gtk_window_set_default_size (GTK_WINDOW (window), 250, 300);
scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow),
GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC);
gtk_container_add (GTK_CONTAINER (window), scrolledwindow);
model = create_model ();
treeview = gtk_tree_view_new ();
add_columns (GTK_TREE_VIEW (treeview));
gtk_tree_view_set_model (GTK_TREE_VIEW (treeview), model);
g_object_unref (G_OBJECT (model));
gtk_container_add (GTK_CONTAINER (scrolledwindow), treeview);
g_signal_connect ((gpointer) window, "delete_event",
G_CALLBACK (gtk_main_quit), NULL);
return window;
}
/* Crea el modelo e inserta un par de filas, en la primera
columna (0) una imagen y en la segunda (1) un texto
alusivo a la imagen.
Solo corresponde a la parte logica, los datos.
*/
static GtkTreeModel *
create_model (void)
{
GtkListStore *model;
GdkPixbuf *left_pixbuf;
GdkPixbuf *right_pixbuf;
GtkTreeIter iter;
model = gtk_list_store_new (2, GDK_TYPE_PIXBUF, G_TYPE_STRING);
left_pixbuf = gdk_pixbuf_new_from_xpm_data (leftarrow_xpm);
right_pixbuf = gdk_pixbuf_new_from_xpm_data (rightarrow_xpm);
gtk_list_store_append (model, &iter);
gtk_list_store_set (model, &iter, 0, left_pixbuf, 1, "izquierda",
-1);
gtk_list_store_append (model, &iter);
gtk_list_store_set (model, &iter, 0, right_pixbuf, 1, "derecha",
-1);
return GTK_TREE_MODEL (model);
}
/*
Define cada columna en el GtkTreeView y como debe mostrarse.
Empaquetamos 2 columnas en una sola. La primera (0) es una
imagen y la segunda (1) un texto, y tiene que relacionarse
1:1 con el modelo, ya que aqui se indica como deben presentarse
los datos (del modelo) al usuario.
*/
static void
add_columns (GtkTreeView * treeview)
{
GtkCellRenderer *renderer;
GtkTreeViewColumn *column;
column = gtk_tree_view_column_new ();
gtk_tree_view_column_set_title (column, "Pixbuf & text in one column");
renderer = gtk_cell_renderer_pixbuf_new ();
gtk_tree_view_column_pack_start (column, renderer, FALSE);
gtk_tree_view_column_set_attributes (column, renderer,
"pixbuf", 0, NULL);
renderer = gtk_cell_renderer_text_new ();
gtk_tree_view_column_pack_start (column, renderer, TRUE);
gtk_tree_view_column_set_attributes (column, renderer,
"text", 1, NULL);
gtk_tree_view_append_column (treeview, column);
}