Capítulo 3. GtkTreeModels para almacenamiento de datos: GtkListStore y GtkTreeStore

Es importante darse cuenta de que es y que no es GtkTreeModel. GtkTreeModel es básicamente solo una 'interface' para el almacenamiento de datos, eso significa que es un conjunto de funciones estandarizadas que permiten a un widget GtkTreeView (y al programador de la aplicación) consultar ciertas caracteristicas de un almacenamiento de datos, por ejemplo cuántas filas existen, que filas tienen hijos, y cuantos hijos tiene una fila en particular. Además provee funciones para obtener datos desde el almacenamiento de datos, y le indica a la vista de árbol los tipos de datos almacenados en el modelo. Cada almacenamiento de datos debe implementar la interfase GtkTreeModel y proveer esas funciones, que pueden ser usadas convirtiendo (vía casting) un almacenamiento en un modelo de árbol con GTK_TREE_MODEL(store). Por si mismo, GtkTreeModel solo provee un modo para consultar las caracteristicas de un almacenamiento de datos y obtener datos existentes, no provee un método para eliminar o agregar filas al almacenamiento o para poner datos en el almacenamiento. Esto se hace usando las funciones especificas de éste.

Gtk+ incorpora dos almacenamientos de datos (modelos): GtkListStore y GtkTreeStore. Como los nombres implican, GtkListStore es usada para listas simples de datos dnde los datos no tienen relaciones jerárquicas, y GtkTreeStore es usada para estructuras de datos de tipo árbol, donde los ítems pueden tener relaciones jerárquicas. Una lista de archivos en un directorio podría ser un ejemplo de una estructura con una lista simple, así como un arbol de directorios es un ejemplo de una estructura de árbol. Una lista es básicamente solo un caso especial de un árbol en el cual ninguno de los items tienen hijos, por lo que uno podría usar un almacenamiento de árbol para mantener una lista simple de ítems también. La única razón por la que GtkListStore existe es para otorgar una interfase mas simple en la que no se deben brindar relaciones jerarquicas, y porque un modelo de lista simple puede ser optimizado para casos en los cuales no existen hijos, lo que la convierte en más rápida y eficiente.

GtkListStore y GtkTreeStore deben brindar la mayoría de los tipos de datos que un desarrollador de aplicaciones pueda querer desplegar en undisplay in a GtkTreeView. Sin embargo, debe notarse que GtkListStore y GtkTreeStore han sido diseñados pensando en la flexibilidad. Si se desea almacenar muchos datos, o tener una gran número de columnas, debe considerarse la posibilidad de implementear modelos personalizados que almacenen y manipulen datos como se desee e implementar la interfase GtkTreeModel. Esto no solo será mas eficiente, sino que probablemente producirá mejor ccódigo a la larga, y brindará mucho más control sobre los datos. Vea abajo para mas detalles sobre cómo implementar modelos personalizados.

Implementaciones de modelos de árboles como GtkListStore y GtkTreeStore se preocuparán del lado visual una vez que sea configurado el GtkTreeView que se desea desplegar. Si se cambian datos en el almacenamiento, el modelo notificará a la vista de árbol y los datos desplegados serán actualizados. Si se agreagan o eliminan filas, el modelo notificará tambien al almacenamiento, y la fila aparecerá o desaparecerá de la vista también.

3.1. Como los datos son organizados en un Almacenamiento

Un modelo (almacenamiento de datos) consta de columnas y filas. Mientras una vista de arbol despliegará cada fila en el modelo como una fila en la vista, las columnas del modelo no deben ser confundidas con las vistas de una columna. Una columna del modelo representa un campo de datos de un ítem que tiene un tipo de datos fijo. Se debe saber que tipos de datos quieren almacenarse cuando se crea un almacenamiento de lista o de árbol, dado que no se pueden agregar nuevos campos despues.

Por ejemplo, podriamos querer desplegar una lista de archivos. Entonces querriamos crear una almacenamiento de lista con dos campos: un campo para almacenar el nombre de archivo (ie. un string) y un campo para almacenar el tamaño del archivo (ie. un entero sin signo). El nombre del archivo sería almacenado en la columna 0 del modelo, y el tamaño del archivo sería almacenado en la columna 1. Para cada archivo agregaríamos una fila al almacenamiento de lista y asociariamos los campos de cada fila con el nombre de archivo y su tamaño.

El sistema de tipos de GLib (GType) se usa para indicar que tipo de datos es almacenado en una columna del modelo. Estos son los tipos mas comunmente usados:

No es necesario entender el sistema de tipos, usualmente será suficiente conocer los tipos recien mencionados, para poder informar al almacenamiento que tipo de datos se desea almacenar. Usuarios avanzados pueden derivar sus propios tipos a partir de los tipos fundamentales de GLib. Para estructuras simples se puederegistrar un nuevo boxed type por ejemplo, pero usualmente no es necesario. G_TYPE_POINTER will often do as well, solo será necesario preocuparse de la reserva de memoria y de liberarla correspondientemente.

El almacenamiento de tipos derivados de GObject (la mayoría GDK_TYPE_FOO y GTK_TYPE_FOO) es un caso especial que será tratado más adelante.

He aquí un ejemplo de como crear un almacenamiento de lista:


  GtkListStore *list_store;

  list_store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_UINT);

Esto crea una nueva lista con dos columnas. La columna 0 almacena un string y la columna 1 almacena un entero sin signo para cada fila. En este punto el modelo no tiene filas todavía, desde luego. Antes de comenzar a añadir filas, debemos echar un vistazo a los distintos modos utilizados para referirse a una fila en particular.