Tabla de contenidos
El control TreeView (control de vista de árbol) muestra
listas y árboles de múltiples columnas. Sustituye los antiguos controles List,
CList, Tree y
CTree por un conjunto de objetos mucho más potente y flexible
que utilizan el patrón Modelo-Vista-Controlador (MVC) para proporcionar las siguientes
funcionalidades:
Obviamente, todas estas posibilidades conllevan el coste de un conjunto de objetos e interfaces significativamente más complejo y que puede llegar a parecer intimidatorio inicialmente. En el resto del capítulo exploraremos los objetos e interfaces de la vista de árbol (TreeView) para comprender sus usos habituales. Los usos más esotéricos tendrán que ser investigados por el lector.
Comenzaremos con una rápida visión general de objetos e interfaces para
posteriormente bucear en la interfaz de TreeModel y en las
clases predefinidas ListStore y
TreeStore.
El control TreeView (vista de árbol) es el objeto
de interfaz de usuario que muestra los datos almacenados en un objeto que implemente
la interfaz TreeModel. En PyGTK 2.0 se proporcionan dos
clases base para modelos de árbol.:
TreeStore (almacén de datos en árbol), que
proporcionan almacenamiento para datos jerárquicos, organizándolos como filas
de un árbol y con los datos en columnas. Cada fila del árbol puede tener cero o más filas
hijas, aunque todas las filas deben tener el mismo número de columnas.ListStore (almacén de datos en lista), que
proporciona almacenamiento para datos tabulares, con una organización en filas
y columnas, de una manera similar a la tabla de una base de datos relacional. Un
ListStore (almacén de datos en lista) realmente consiste en
una versión simplificada de un TreeStore
(almacén de datos en árbol), cuyas filas no tienen descendientes. Fue creada para
proporcionar una interfaz más sencilla (y presuntamente más eficiente) a un modelo de
datos tan común. Y,estos dos modelos adicionales se superponen (o se interponen) a los modelos base:
TreeModelSort,
que proporciona un modelo en el que los datos del modelo de árbol subyacente
se mantienen ordenados. Y,TreeModelFilter, que proporciona un modelo que
contiene un subconjunto de los datos del modelo subyacente. Este modelo únicamente
está disponible desde la versión de PyGTK 2.4 y posteriores.Un TreeView (vista de árbol) muestra todas las filas que
contiene un TreeModel, pero permite mostrar selectivamente
algunas de las columnas. También es posible presentar las columnas en un orden diferente
al de almacenamiento en el TreeModel.
Un TreeView usa objetos del tipo
TreeViewColumn (columnas de vista de árbol) para organizar la
visualización de los datos en columnas. Cada TreeViewColumn
muestra una columna con un encabezado opcional que puede contener los datos de
diversas columnas de un TreeModel. Los objetos
TreeViewColumn se empaquetan (de forma semejante a los
contenedores HBox) con objetos
CellRenderer (intérpretes de celda), para generar la visualización
de los datos asociados situados en una fila y columna de un
TreeModel. Existen tres clases de
CellRenderer predefinidas:
CellRendererPixbuf, que muestra una imagen del tipo
pixbuf en las celdas de un TreeViewColumn.CellRendererText, que muestra una cadena
en las celdas de un TreeViewColumn. Si es necesario convierte
los datos de la columna a cadenas de texto. Por ejemplo, si se mostrase una columna
de datos consistente en números en coma flotante,
el CellRendererText los
convertiría en cadenas de texto antes de mostrarlos.CellRendererToggle, que muestra un valor
booleano como un botón conmutable en las celdas de un
TreeViewColumn.Una TreeViewColumn puede contener varios objetos
CellRenderer para proporcionar una columna que, por ejemplo,
pueda contener una imagen y un texto juntos.
Finalmente, los objetos TreeIter (iterador de árbol),
TreeRowReference (referencia de fila de árbol) y
TreeSelection (selección de árbol) proporcionan un puntero
transitorio a la fila de un TreeModel, un puntero persistente a
la fila de un TreeModel y un objeto que gestiona una selección en
una TreeView.
La visualización de un TreeView se compone
de las siguientes operaciones generales (aunque no necesariamente en este orden):
TreeModel),
generalmente un ListStore o un
TreeStore con una o más columnas de un tipo de
datos determinado.TreeView y se asocia al modelo
de árbol.TreeViewColumn
y se insertan en el TreeView. Cada una de ellas resultará en la
visualización de una columna.TreeViewColumn se crea uno o más
intérpretes de celda CellRenderer, que son añadidos a cada
TreeViewColumn.CellRenderer
para indicar de qué columnas del modelo de árbol han de tomar los datos del atributo, como por
ejemplo, el texto que se ha de mostrar. Esto permite que los
CellRenderer muestren las columnas de cada fila de forma
distinta.TreeView se inserta y es mostrado en una
ventana (Window) o una ventana con barras de desplazamiento
(ScrolledWindow).TreeView rastreará de forma automática los cambios.El programa de ejemplo basictreeview.py
ilustra la creación y visualización de un objeto sencillo
TreeView:
1 #!/usr/bin/env python
2
3 # example basictreeview.py
4
5 import pygtk
6 pygtk.require('2.0')
7 import gtk
8
9 class BasicTreeViewExample:
10
11 # close the window and quit
12 def delete_event(self, widget, event, data=None):
13 gtk.main_quit()
14 return gtk.FALSE
15
16 def __init__(self):
17 # Create a new window
18 self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
19
20 self.window.set_title("Basic TreeView Example")
21
22 self.window.set_size_request(200, 200)
23
24 self.window.connect("delete_event", self.delete_event)
25
26 # create a TreeStore with one string column to use as the model
27 self.treestore = gtk.TreeStore(str)
28
29 # we'll add some data now - 4 rows with 3 child rows each
30 for parent in range(4):
31 piter = self.treestore.append(None, ['parent %i' % parent])
32 for child in range(3):
33 self.treestore.append(piter, ['child %i of parent %i' %
34 (child, parent)])
35
36 # create the TreeView using treestore
37 self.treeview = gtk.TreeView(self.treestore)
38
39 # create the TreeViewColumn to display the data
40 self.tvcolumn = gtk.TreeViewColumn('Column 0')
41
42 # add tvcolumn to treeview
43 self.treeview.append_column(self.tvcolumn)
44
45 # create a CellRendererText to render the data
46 self.cell = gtk.CellRendererText()
47
48 # add the cell to the tvcolumn and allow it to expand
49 self.tvcolumn.pack_start(self.cell, True)
50
51 # set the cell "text" attribute to column 0 - retrieve text
52 # from that column in treestore
53 self.tvcolumn.add_attribute(self.cell, 'text', 0)
54
55 # make it searchable
56 self.treeview.set_search_column(0)
57
58 # Allow sorting on the column
59 self.tvcolumn.set_sort_column_id(0)
60
61 # Allow drag and drop reordering of rows
62 self.treeview.set_reorderable(True)
63
64 self.window.add(self.treeview)
65
66 self.window.show_all()
67
68 def main():
69 gtk.main()
70
71 if __name__ == "__main__":
72 tvexample = BasicTreeViewExample()
73 main()
En programas reales el TreeStore probablemente
se llenaría de datos después de que la visualización del TreeView
se produjese por una acción del usuario. Nos detendremos en los detalles de las
interfaces de TreeView en secciones posteriores.
Figura 14.1, “Programa elemental de ejemplo de TreeView” muestra la ventana creada por el programa
basictreeview.py
tras la expanxión de un par de filas madre.
Ahora examinemos la interfaz de TreeModel y los
modelos que la implementan.