![]() | ![]() | Programación en el entorno GNOME | ![]() |
---|
Tabla de contenidos
Es habitual que se necesiten mostrar estructuras de datos relativamente complejas dentro de las interfaces gráficas de las aplicaciones. Estos datos en muchos casos están relacionados al pertencer a un mismo conjunto y se pueden mostrar al usuario como una lista. Pero en ocasiones, los elementos de esta lista a su vez son estructuras de datos necesitando mostrarse a su vez como nuevas listas.
Para este tipo de situaciones dentro de GTK2 se ha creado el potente y flexible control (widget) GtkTreeView/Data, un control que sigue el diseño MVC (modelo/vista/controlador) de gtk2 y que como veremos, nos permite mostrar con una estructura compleja al usuario de forma que para éste, su manejo sea sencillo y rápido.
La idea básica es proporcionar un control que permite representar datos en forma de árbol, donde cada nodo a su vez puede ser un nuevo árbol. Las listas son un caso especial de este caso general ya que son sólo un nivel de nodos simples sin ramificaciones.
Nada mejor para romper el hielo que un ejemplo simple de una lista basada en GtkTreeView. Para ello hemos cogido dos ejemplos del tutorial de gtk2 y lo hemos simplificado. La idea es mostrar al usuario una lista cerrada de la compra, es decir, un conjunto de productos que el usuario tendrá que comprar. En el segundo ejemplo veremos como se puede mostrar información organizada en forma anidada, es decir, que un elemento de datos puede a su vez tener otros elementos que dependen de él.
Vamos a ver en el ejemplo varias partes bien diferenciadas. Dentro del "main" se crea la ventana principal de la aplicación, la cual contiene una etiqueta y nuestra lista.
En la parte específica del uso de GtkTreeView nos encontramos con una llamada a "create_model", la cual se encarga de crear el modelo de datos de la lista, el cual será representado a través de la vista, que creamos utilizando este modelo de datos. Tras crear la vista, añadimos las columnas que queremos que el usuario vea y añadimos la vista al contenedor desde el que se visualiza en la pantalla principal.
Lo más importante de este ejemplo es ver como están perfectamente desacoplados los datos y la vista. Vemos que se asocian cuando se crea la vista con el modelo de datos, pero a la hora de visualizar, podemos elegir que parte de los datos se van a mostrar. En este caso los datos sólo tienen un campo, que es el que se muestra, pero como iremos viendo esto puede no ser así.
Ya habiendo visto cada parte resumidamente, iremos desglosando el ejemplo en varias partes de las cuales explicaremos paso a paso que se va a haciendo, por ello que mejor que empezar que con nuestro querido main :-)
int main (int argc, char *argv[]) { gtk_init (&argc, &argv); window = GTK_WIDGET (do_cells ()); gtk_widget_show_all (window); gtk_main (); }
Aquí inicializamos la libreria gtk y una vez ya creada nuestra ventana, llamamos al método do_cells() que es el que se encargará de crear las ventana donde se dispondrá nuestro GtkTreeView. Posteriormente se visualizarán nuestra ventana y se ejecutará el bucle gtk_main().
Ya visto que se llama a la función do_cells podemos ver que ahí lo único que hace es crear la ventana y los consecutimos contenedores, además de crear nuestro modelo de datos, nuestro GtkTreeModel a partir de la función create_model() que ahora veremos a continuación. Una vez esto lo cogerá nuestra vista de árbol y se embeberá dentro del sw que está dentro del hbox. Esta parte no es necesaria ver de forma exhaustiva ya que está perfectamente explicada en la parte relativa a gtk por lo que seguro que lo entendeis :)
La parte de "create_model()" es la que se encarga de crear el modelo de datos de nuestro árbol en el widget model, posteriormente se creará el modelo de vistas del arbol además de la columna que le añadiremos, llamada productos con la función add_columns.
Ya visto que llama a create_model, analizaremos dicha función. Esta función se encarga de recorrer el array donde hemos metido todos los elementos de la lista de la compra sobre un widget GtkListStore que no es más que una lista, lo iremos recorriendo el array e iremos almacenando cada uno de los elementos del array en lo que será nuestro modelo de datos del árbol, en definitiva nuestra lista que con el adecuado casting a GTK_TREE_MODEL podéis ver que nos devuelve un widget del tipo GtkTreeModel el cual pasamos a asociar nuestra vista con:
treeview = gtk_tree_view_new_with_model (model);
A partir de este momento, cuando necesitemos trabajar con los datos lo haremos únicamente con el GtkListStore, y dichos cambios se reflejarán de forma automática dentro de la vista. Por ejemplo, el añadir un nuevo producto.
Sólo queda ver el añadido de una celda productos con la función add_columns sobre nuestra vista de árbol GtkTreeView.
En la función add_columns() utilizaremos un tipo widget GtkCellRenderer con el texto "producto" que insertaremos en el árbol de la siguiente manera:
renderer = gtk_cell_renderer_text_new (); gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview), -1, "Producto", renderer, "text", COLUMN_PRODUCT, NULL);
Como podéis ver es bastante sencillo, la única parte no comentada es la de la introducción de datos dentro del array, ya correspondiente a la parte de glib, no por ello complicada, unicamente vamos añadiendo valores sobre el array de la siguiente forma:
foo.product = g_strdup ("sardinas en aceite"); g_array_append_vals (articles, &foo, 1);
Luego estos datos serán los que utilizemos en la lista para almacenar los datos y conseguir nuestro modelo de árbol GtkTreeModel.
Como podéis ver no es complicado, unicamente hay que diferenciar entre el modelo de datos que es el que utilizamos para toda la manipulación del contenido del árbol y luego el GtkTreeView que es el que utilizaremos para la parte correspondiente a la muestra por pantalla de ese modelo de datos ya creado.
Para concluir este primer ejemplo, resumir que hemos utilizado un modelo de datos "GtkListStore" que hemos podido utilizar de forma sencilla y asociarlo a la vista pero, ¿y si nuestros datos forman tienen una estructura más compleja? ¿Y si no son simplemente cadenas de caractéres si no que son completos objetos con mucha información? ¿Es capaz GtkTreeView de visualizar estos objetos según nuestras necesidades?
La respuesta es que sí. Tenemos el modelo de datos "GtkListStore" para los habituales casos de tratamiento de cadenas de caracteres en una lista y, "GtkTreeStore" para las cadenas de caractéres que se organizan en árbol. Es muy útil tenerlos ya predefinidos ya que los utilizaremos muy amenudo. Pero nada nos impide crearnos nuestros propios modelos de datos, tal y como vamos a mostrar en el siguiente apartado.
<< Widgets de desplazamiento | GtkTreeModel: El modelo de datos >> |