문제

나는 TreeView에 트리를 표시하기 위해 내 자신의 QAbstractItemModel을 작성했습니다.최상위 항목이 표시되지만 디렉터리를 확장하면 앱이 닫히고 다음 메시지가 콘솔에 기록됩니다."분할 오류" 내가 뭘 잘못하고 있는 걸까요?내 코드의 단순화된 버전은 다음과 같습니다.

#!/usr/bin/env python

import sys
from PyQt4 import QtCore, QtGui


class TreeModel(QtCore.QAbstractItemModel):
    NAME = 0
    FILEID = QtCore.Qt.UserRole + 1
    horizontalHeaderLabels = ["File Name",]
    inventory = None

    def set_tree(self, inventory, root_item):
        self.emit(QtCore.SIGNAL("layoutAboutToBeChanged()"))
        self.inventory = inventory
        self.id2fileid = []
        self.fileid2id = {}
        self.dir_children_ids = {}
        self.parent_ids = []

        # Create internal ids for all items in the tree for use in
        # ModelIndex's.
        root_fileid = root_item.file_id
        self.append_fileid(root_fileid, None)
        remaining_dirs = [root_fileid,]
        while remaining_dirs:
            dir_fileid = remaining_dirs.pop(0)
            dir_id = self.fileid2id[dir_fileid]
            dir_children_ids = []
            for child in inventory[dir_fileid].children:
                id = self.append_fileid(child.file_id, dir_id)
                dir_children_ids.append(id)
                if child.children:
                    remaining_dirs.append(child.file_id)

                if len(self.id2fileid) % 100 == 0:
                    QtCore.QCoreApplication.processEvents()
            self.dir_children_ids[dir_id] = dir_children_ids

        self.emit(QtCore.SIGNAL("layoutChanged()"))

    def append_fileid(self, fileid, parent_id):
        ix = len(self.id2fileid)
        self.id2fileid.append(fileid)
        self.parent_ids.append(parent_id)
        self.fileid2id[fileid] = ix
        return ix

    def columnCount(self, parent):
        if parent.isValid():
            return 0
        return len(self.horizontalHeaderLabels)

    def rowCount(self, parent):
        if self.inventory is None:
            return 0
        parent_id = parent.internalId()
        if parent_id not in self.dir_children_ids:
            return 0
        return len(self.dir_children_ids[parent_id])

    def _index(self, row, column, parent_id):
        item_id = self.dir_children_ids[parent_id][row]
        return self.createIndex(row, column, item_id)

    def index(self, row, column, parent = QtCore.QModelIndex()):
        if self.inventory is None:
            return self.createIndex(row, column, 0)
        parent_id = parent.internalId()
        return self._index(row, column, parent_id)

    def sibling(self, row, column, index):
        sibling_id = child.internalId()
        if sibling_id == 0:
            return QtCore.QModelIndex()
        parent_id = self.parent_ids[child_id]
        return self._index(row, column, parent_id)

    def parent(self, child):
        child_id = child.internalId()
        if child_id == 0:
            return QtCore.QModelIndex()
        item_id = self.parent_ids[child_id]
        if item_id == 0 :
            return self.createIndex(0, 0, item_id)

        parent_id = self.parent_ids[item_id]
        row = self.dir_children_ids[parent_id].index(item_id)
        return self.createIndex(row, 0, item_id)

    def hasChildren(self, parent):
        if self.inventory is None:
            return False

        parent_id = parent.internalId()
        return parent_id in self.dir_children_ids

    def data(self, index, role):
        if not index.isValid():
            return QtCore.QVariant()

        fileid = self.id2fileid[index.internalId()]

        if role == self.FILEID:
            return QtCore.QVariant(fileid)

        item = self.inventory[fileid]

        column = index.column()
        if column == self.NAME:
            if role == QtCore.Qt.DisplayRole:
                return QtCore.QVariant(item.file_name)

        return QtCore.QVariant()

    def flags(self, index):
        if not index.isValid():
            return QtCore.Qt.ItemIsEnabled

        return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable

    def headerData(self, section, orientation, role):
        if orientation == QtCore.Qt.Horizontal and role == QtCore.Qt.DisplayRole:
            return QtCore.QVariant(self.horizontalHeaderLabels[section])
        return QtCore.QVariant()

inventory = {}

class InventoryItem():

    def __init__(self, file_id, file_name, children=[]):
        self.file_id = file_id
        self.file_name = file_name
        self.children = children
        global inventory
        inventory[file_id] = self

root_item = InventoryItem("root-id", "", [
    InventoryItem("dir1-id", "dir1", [
        InventoryItem("file1-id", "file1")
    ]),
    InventoryItem("file1-id", "file1")
])

app = QtGui.QApplication(sys.argv)

model = TreeModel()
model.set_tree(inventory, root_item)

tree_view = QtGui.QTreeView()
tree_view.setModel(model)

tree_view.show()
app.exec_()

정식 버전은 다음 지점에서 찾을 수 있습니다. https://code.launchpad.net/~garyvdm/qbzr/trees, lib/browse.py 파일에서

도움이 되었습니까?

해결책 3

문제는 QtCore.QModelIndex()를 반환해야 할 때 parent()에서 루트에 대한 유효한 인덱스를 반환했다는 것입니다.

이런 종류의 작업을 디버깅할 수 있다면 여전히 좋을 것입니다. 아직 어떻게 해야 할지 모르겠습니다.

다른 팁

modeltest.py 모듈을 사용하십시오! 다른 시나리오에 대한 모델을 연습합니다. PYQT 소스 코드 패키지 내부의 / Contrib / Directory에서 찾을 수 있습니다.

QT가 여전히 사용하고 싶어하는 Python에 의해 수집 된 쓰레기가 있습니다. 이러한 오류는 추적하기 어렵습니다. 첫 번째 단계로, 나는이 줄을 추가하기 전후에 추가하는 것이 좋습니다. setModel(model):

tree_view.model = model

이것은 트리 객체의 파이썬 부분에서 모델의 참조를 유지합니다.

도움이되지 않으면 코드가 충돌을 멈출 때까지 코드를 제거해야합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top