2015-01-12 5 views
2

Мне сложно понять, как установить многоуровневый QTree с помощью QTreeView и QStandardItemModel.Многоуровневый QTreeView

Вот что у меня есть:

from PySide.QtGui import * 
import sys 

class MainFrame(QWidget): 
    def __init__(self): 
     QWidget.__init__(self) 

     tree = {'root': { 
        "1": ["A", "B", "C"], 
        "2": { 
         "2-1": ["G", "H", "I"], 
         "2-2": ["J", "K", "L"]}, 
        "3": ["D", "E", "F"]} 
     } 

     self.tree = QTreeView(self) 
     root_model = QStandardItemModel() 
     self.tree.setModel(root_model) 

     for r,root in enumerate(sorted(tree)): 
      root_item = QStandardItem(root) 
      root_model.setItem(r,root_item) 

      for c,child in enumerate(sorted(tree[root])): 
       child_model = QStandardItemModel(root_model) 
       child_item = QStandardItem(child) 
       child_model.setItem(c, child_item) 

       for gc, grand_child in enumerate(sorted(tree[root][child])): 
        grand_child_model = QStandardItemModel(child_model) 
        grand_child_item = QStandardItem(grand_child) 
        grand_child_model.setItem(gc,grand_child_item) 

        if type(tree[root][child]) == dict: 
         for ggc, gran_grand_child in enumerate(sorted(tree[root][child][grand_child])): 
          gran_grand_child_model = QStandardItemModel(grand_child_model) 
          gran_grand_child_item = QStandardItem(gran_grand_child) 
          gran_grand_child_model.setItem(ggc, gran_grand_child_item) 

if __name__ == "__main__": 
    app = QApplication(sys.argv) 
    main = MainFrame() 
    main.show() 
    sys.exit(app.exec_()) 

Я хочу, чтобы выглядеть следующим образом:

tree

До сих пор только «корень» пункт показывает, что это не бросать какие-либо ошибки.

Кроме того, я сделал это для петель в некоторой спешке, это очень трудно читать/понимать, потому что у него слишком много вложенных циклов. Интересно, есть ли лучший способ расширить дерево на основе исходного dict.

ответ

5

Вы создаете модель для каждого элемента. Это неверно. Вы должны использовать .appendRow/.insertRow на предмет добавления дочерних элементов.

Что касается ваших циклов, я бы, вероятно, использовал рекурсивный метод для заполнения дерева. Вот что я хотел бы сделать:

from PySide.QtGui import * 
import sys 
import types 

class MainFrame(QWidget): 
    def __init__(self): 
     QWidget.__init__(self) 

     tree = {'root': { 
        "1": ["A", "B", "C"], 
        "2": { 
         "2-1": ["G", "H", "I"], 
         "2-2": ["J", "K", "L"]}, 
        "3": ["D", "E", "F"]} 
     } 

     self.tree = QTreeView(self) 
     layout = QHBoxLayout(self) 
     layout.addWidget(self.tree) 

     root_model = QStandardItemModel() 
     self.tree.setModel(root_model) 
     self._populateTree(tree, root_model.invisibleRootItem()) 

    def _populateTree(self, children, parent): 
     for child in sorted(children): 
      child_item = QStandardItem(child) 
      parent.appendRow(child_item) 
      if isinstance(children, types.DictType): 
       self._populateTree(children[child], child_item) 

if __name__ == "__main__": 
    app = QApplication(sys.argv) 
    main = MainFrame() 
    main.show() 
    sys.exit(app.exec_()) 

PS: Вы также не используете макеты для главного окна. Я добавил его выше.

pSV2: Тип проверка лучше избегать в питона, если это возможно, но это своего рода необходимо, как вы структурированную ваш tree. Было бы лучше, если вы структурированы по-другому, как dict все, как может быть:

tree = {'root': { 
      '1': {'A':{}, 'B':{}, 'C':{}}, 
      ... 
     } 
+0

Отлично, приятно прикасаться на рекурсии, никогда бы не подумал об этом. –