Solución: QTreeView dentro de un QComboBox (PySide)

Muchos deben haber sufrido el problema de no poder obtener o fijar datos al usar un QTreeView dentro de un QComboBox, y en internet no he encontrado ninguna solución completa.

El problema es que la implementación de QAbstractItemModel que maneja la clase QComboBox es del tipo lista (QAbstractListModel) o de un solo nivel (una columna particular de QAbstractTableModel por ejemplo). Y por el contrario, QTreeView utiliza un modelo con anidaciones (Una implementación mucho mas completa de QAbstractItemModel).

Los metodos como void QComboBox::setCurrentIndex(int) ó int QComboBox::currentIndex() de QComboBox utilizan, por lo dicho anteriormente, argumentos y retornos enteros, que corresponden al numero de fila (row) dentro del modelo. Por tal motivo, si queremos que esto funcione al utilizar un modelo de datos y una vista de tipo arbol (u objetos anidados), vamos a tener problemas y el comportamiento va a ser extraño, porque en realidad siempre va a estar trabajando con el nivel inicial del modelo (Root).
Para poder trabajar con un modelo de datos en arbol, vamos a tener que usar indices (instancias de QModelIndex), que nos brinden información de la posición del elemento que queremos, y mas importante aún, información sobre sus indices superiores (parents)

Para manejar esto de la manera mas transparente, simple e inteligente posible, sin salirnos de nuestro QComboBox, decidí hacer mi propia implementación de algunos métodos de esta clase a nivel global. De esta manera, de acuerdo al tipo de vista que tengamos dentro del combo, los métodos van a manejar enteros o indices.

Basta de charlas y vamos a los bifes, que siempre se aprende mas rapido de esa manera.
Voy a intentar hacerlo lo mas simple y funcional posible.

En primera instancia vamos a generar el siguiente archivo:

Luego simplemente debemos importarlo al principio de la aplicación para que se modifiquen las clases antes de empezar a utilizarlas!

Atención: El siguiente ejemplo es pseudo-codigo (o una mezcla), y no es funcional, simplemente ilustrativo

La pregunta que les puede surgir ahora es la siguiente: “¿Como hago para recorrer todos los indices dentro del modelo de árbol, para saber cual es el que queremos utilizar como indice predeterminado del combobox?

Como la exploración es recursiva, decidi armar una funcion que nos devuelva cada uno de los indices de manera iterable, para que podamos compararlo con el dato que querramos!

Aca va la declaración

Y aca su utilización (pseudo-codigo, o algo asi inventado por mi)

Para obtener el el itemData del TreeItem correspondiente al Index actual dentro del QTreeView, se hace de la misma forma que siempre en un combobox

self.view.ui.comboCategoria.itemData(self.view.ui.comboCategoria.currentIndex())

Espero que les haya servido!

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *