Это действительно очень просто.
Во-первых, подключите расширенный сигнал дерева к обработчику и заполните дерево элементами верхнего уровня корня.
Когдасигнал срабатывает, он передает индекс расширенного элемента в обработчик.Затем обработчик может использовать это, чтобы проверить, есть ли у элемента дочерние элементы, например, с помощью метода hasChildren .
Если у элемента уже есть дочерние элементы, ничего не делать;в противном случае, заполните его теми элементами верхнего уровня, которые подходят для этого элемента.
ОБНОВЛЕНИЕ
Ниже приведен скрипт, демонстрирующий, как построить дерево динамически.
Для простоты в демоверсии используется QTreeWidget , что исключает необходимость в отдельной модели.Дополнительные данные хранятся в дереве с помощью QTreeWidgetItem.setData .
Обратите внимание, что импорт sip
вверху необходим только для совместимости между Python 2 и 3 (см. здесь для деталей).Если вы используете Python 2, он не нужен.
import sip
sip.setapi('QVariant', 1)
from PyQt4 import QtGui, QtCore
class Window(QtGui.QTreeWidget):
def __init__(self):
QtGui.QTreeWidget.__init__(self)
self.setHeaderHidden(True)
self.itemExpanded.connect(self.handleExpanded)
self.itemClicked.connect(self.handleClicked)
self.handleExpanded(self.invisibleRootItem())
def depth(self, item):
depth = 0
while item is not None:
item = item.parent()
depth += 1
return depth
def requestData(self):
for title in 'One Two Three Four Five'.split():
yield title, 'additional data'
def addItems(self, parent):
depth = self.depth(parent)
for title, data in self.requestData():
item = QtGui.QTreeWidgetItem(parent, [title])
item.setData(0, QtCore.Qt.UserRole, data)
if depth < 3:
item.setChildIndicatorPolicy(
QtGui.QTreeWidgetItem.ShowIndicator)
def handleExpanded(self, item):
if item is not None and not item.childCount():
self.addItems(item)
def handleClicked(self, item, column):
print(item.data(column, QtCore.Qt.UserRole).toPyObject())
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())