Lors de la création d'un modèle en forme d'arbre avec PySide, vous souhaiterez peut-être accéder à tous les éléments de manière séquentielle.
Si vous utilisez QTreeWidget, vous pouvez y accéder séquentiellement avec QTreeWidgetItemIterator. (Puisqu'il s'agit d'une bibliothèque pour C ++, c'est un peu gênant à utiliser avec python) Je l'ai créé parce que je veux utiliser l'itérateur pour QStandardItemModel et mon propre modèle.
Le code est python2, mais comme il n'utilise pas xrange, il fonctionne comme dans python3.
#! usr/bin/python
# -*- coding: utf-8 -*-
from __future__ import unicode_literals, print_function, absolute_import
from PySide.QtCore import *
from PySide.QtGui import *
def model_iter(model, parent_index=QModelIndex(), col_iter=True):
"""Itérateur de modèle
:rtype: generator(QModelIndex)
:type col_iter: bool
:type parent_index: QModelIndex
:type model: QAbstractItemModel
"""
index = model.index(0, 0, parent_index)
while True:
if col_iter:
for col in range(0, model.columnCount(parent_index)):
yield index.sibling(index.row(), col)
else:
yield index
if model.rowCount(index) > 0:
for _ in model_iter(model, index, col_iter):
yield _
index = index.sibling(index.row() + 1, index.column())
if not index.isValid():
break
C'est facile à utiliser, il suffit de passer le modèle et il retournera l'itérateur.
tree_model = QStandardItemModel()
item = QStandardItem("A")
item.appendRow(QStandardItem("A-1"))
item.appendRow(QStandardItem("A-2"))
tree_model.appendRow(item)
item = QStandardItem("B")
item.appendRow(QStandardItem("B-1"))
item.appendRow(QStandardItem("B-2"))
tree_model.appendRow(item)
item = QStandardItem("C")
tree_model.appendRow(item)
print([_.data() for _ in model_iter(tree_model)])
>>> [u'A', u'A-1', u'A-2', u'B', u'B-1', u'B-2', u'C']
Non seulement le type d'arbre mais également le modèle de type table sont pris en charge.
table_model = QStandardItemModel(3, 3)
for r in range(3):
for c in range(3):
table_model.setItem(r, c, QStandardItem("%d-%d" % (r, c)))
print([_.data() for _ in model_iter(table_model)])
>>> [u'0-0', u'0-1', u'0-2', u'1-0', u'1-1', u'1-2', u'2-0', u'2-1', u'2-2']
J'ai également créé un itérateur inversé.
def model_iter_r(model, parent_index=QModelIndex(), col_iter=True):
"""Itérateur de modèle (ordre inverse)
:rtype: generator(QModelIndex)
:type col_iter: bool
:type parent_index: QModelIndex
:type model: QAbstractItemModel
"""
index = model.index(model.rowCount(parent_index) - 1, 0, parent_index)
while True:
if model.rowCount(index) > 0:
for _ in model_iter_r(model, index, col_iter):
yield _
if col_iter:
for col in range(model.columnCount(parent_index) - 1, -1, -1):
yield index.sibling(index.row(), col)
else:
yield index
index = index.sibling(index.row() - 1, index.column())
if not index.isValid():
break
L'utilisation est exactement la même que celle dans l'ordre.
print([_.data() for _ in model_iter_r(tree_model)])
>>> [u'C', u'B-2', u'B-1', u'B', u'A-2', u'A-1', u'A']
print([_.data() for _ in model_iter_r(table_model)])
>>> [u'2-2', u'2-1', u'2-0', u'1-2', u'1-1', u'1-0', u'0-2', u'0-1', u'0-0']
La structure arborescente est également suivie dans l'ordre inverse.
L'accès séquentiel aux modèles est une fonction fréquemment utilisée, mais il est difficile de mettre en œuvre chacun d'eux car il utilise récursif. Il est pratique de copier cette fonction.
La prochaine fois, nous utiliserons cette fonction pour créer un objet de recherche.
Recommended Posts