14.8. Selecciones TreeSelections

14.8.1. Obtención de TreeSelection

Las TreeSelections son objetos que gestionan las selecciones en un TreeView. Cuando se crea un TreeView también se crea automáticamente una TreeSelection. Puede obtenerse la TreeSelection de una TreeView utilizando el método:

  treeselection = treeview.get_selection()

Se puede obtener el TreeView asociado a una TreeSelection con el método:

  treeview = treeselection.get_treeview()

14.8.2. Modos de una selección TreeSelection

Una selección TreeSelection soporta los siguientes modos de selección:

gtk.SELECTION_NONE

No se permite hacer una selección.

gtk.SELECTION_SINGLE

Se permite una única selección haciendo click.

gtk.SELECTION_BROWSE

Se permite una única selección navegando con el puntero.

gtk.SELECTION_MULTIPLE

Se pueden seleccionar múltiples elementos de una vez.

Se puede obtener el modo actual de selección llamando al método:

  mode = treeselection.get_mode()

El modo puede establecerse utilizando:

  treeselection.set_mode(mode)

donde mode es uno de los modos previamente indicados.

14.8.3. Obtención de la Selección

El método que es necesario usar par obtener la selección depende del modo actual de selección. Si el modo de selección es gtk.SELECTION_SINGLE o gtk.SELECTION_BROWSE, se debe usar el siguiente método:

  (model, iter) = treeselection.get_selected()

que devuelve una tupla de dos elementos que contiene model, el TreeModel usado por el TreeView asociado con treeselection e iter, un iterador TreeIter que apunta a la fila seleccionada. Si no hay una fila seleccionada entonces iter es None. Si el modo de selección es gtk.SELECTION_MULTIPLE se produce una excepción TypeError.

Si se tiene una TreeView que utiliza el modo de selección gtk.SELECTION_MULTIPLE entonces se debería usar el método:

  (model, pathlist) = treeselection.get_selected_rows()

que devuelve una tupla de dos elementos que contiene el modelo de árbol y una lista de los caminos de árbol de las filas seleccionadas. Este método no está disponible en PyGTK 2.0, por lo que es necesario utilizar una función auxiliar para obtener la lista mediante:

  treeselection.selected_foreach(func, data=None)

donde func es una función que es llamada para cada fila seleccionada con data. La signatura de func es:

  def func(model, path, iter, data)

donde model es el TreeModel, path es el camino de árbol de la fila seleccionada e iter es un TreeIter que señala la fila seleccionada.

Este método puede ser usado para simular el método get_selected_row() así:

  ...
  def foreach_cb(model, path, iter, pathlist):
      list.append(path)
  ...
  def my_get_selected_rows(treeselection):
      pathlist = []
      treeselection.selected_foreach(foreach_cb, pathlist)
      model = sel.get_treeview().get_model()
      return (model, pathlist)
  ...

El método selected_foreach() no puede usarse para modificar el modelo de árbol o la selección, aunque sí permite cambiar los datos de las filas.

14.8.4. Uso de una Función de TreeSelection

Si se desea un control definitivo sobre la selección de filas se puede establecer una función que será llamada antes de que se seleccione o deselecciones una fila mediante el método:

  treeselection.set_select_function(func, data)

donde func es una función de retrollamada y data son los datos de usuario que se pasarán a func cuando es llamada. func tiene la signatura:

  def func(selection, model, path, is_selected, user_data)

donde selection es la selección TreeSelection, model es el TreeModel usado con el TreeView asociado con selection, path es el camino de árbol de la fila seleccionada, is_selected es TRUE si la fila está actualmente seleccionada y user_data es data. func debería devolver TRUE si el estado de selección de la fila debería ser conmutado.

Establecer una función de selección es útil en estos casos:

  • se quiere controlar la selección o deselección de una fila en función de alguna información adicional de contexto. Se necesitará indicar de alguna manera que el cambio de selección no se puede llevar a cabo y, tal vez, el porqué. Por ejemplo, se puede diferenciar visualmente la fila o mostar un diálogo emergente del tipo MessageDialog.
  • se necesita mantener una lista propia de filas seleccionadas o deseleccionadas, aunque esto mismo se puede hacer, con algo más de esfuerzo, conectándose a la señal "changed".
  • se quiere hacer algún procesado adicional antes de que una fila sea seleccionada o deseleccionada. Por ejemplo, cambiar el aspecto de la fila o modificar los datos de la misma.

14.8.5. Selección y Deselección de Filas

Se puede cambiar la selección dentro de un programa utilizando los siguientes métodos:

  treeselection.select_path(path)
  treeselection.unselect_path(path)

  treeselection.select_iter(iter)
  treeselection.unselect_iter(iter)

Estos métodos seleccionan o deseleccionan una única fila que se especifica bien con path, un camino de árbol, o iter, un iterador TreeIter que apunta a la fila. Los siguientes métodos seleccionan o deseleccionan varias filas de una vez:

  treeselection.select_all()
  treeselection.unselect_all()

  treeselection.select_range(start_path, end_path)
  treeselection.unselect_range(start_path, end_path)

El método select_all() precisa que el modo de selección sea gtk.SELECTION_MULTIPLE al igual que el método select_range(). Los métodos unselect_all() y unselect_range() funcionarán con cualquier modo de selección. Nótese que el método unselect_all() no está disponible en PyGTK 2.0

Se puede comprobar si una fila está seleccionada utilizando uno de los siguientes métodos:

  result = treeselection.path_is_selected(path)
  result = treeselection.iter_is_selected(iter)

que devuelven TRUE si la fila especificada por path o iter está actualmente seleccionada. Se puede obtener el número de filas seleccionadas con el método:

  count = treeselection.count_selected_rows()

Este método no está disponible en PyGTK 2.0 por lo que es preciso simularlo utilizando el método selected_foreach() de forma parecida a la simulación del método get_selected_rows() de la sección Obtención de la Selección. Por ejemplo:

  ...
  def foreach_cb(model, path, iter, counter):
      counter[0] += 1
  ...
  def my_count_selected_rows(treeselection):
      counter = [0]
      treeselection.selected_foreach(foreach_cb, counter)
      return counter[0]
  ...