Question

J'ai écrit mon propre QAbstractItemModel montrer un arbre dans TreeView. Il montre les éléments de haut niveau, mais lorsque vous développez un répertoire, l'application se ferme, le message suivant est écrit à la console: « Segmentation fault » Qu'est-ce que je fais mal qui cause cela. Voici une version simplifed de mon code:

#!/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_()

La version complète peut être trouvée dans cette branche: https: //code.launchpad. net / ~ garyvdm / qbzr / arbres , dans le fichier lib / browse.py

Était-ce utile?

La solution 3

Le problème était que je rentrais un indice valable pour la racine parent () quand je serais été retournais QtCore.QModelIndex ().

Il serait toujours agréable d'être en mesure de déboguer ce genre de chose, que je ne sais toujours pas comment faire.

Autres conseils

Utilisez le module modeltest.py! Il exerce votre modèle pour différents scénarios. Vous pouvez le trouver dans le répertoire / contrib / répertoire à l'intérieur du paquet code source PyQt.

Quelque chose est recueillie par les ordures Python qui Qt veut toujours utiliser. Ces erreurs sont difficiles à trouver. Dans un premier temps, je suggère d'ajouter cette ligne avant ou après setModel(model):

tree_view.model = model

Cela permet de garder une référence du modèle dans la partie Python de l'objet arbre.

Si cela ne fonctionne pas, vous devrez démonter votre code jusqu'à ce qu'il cesse de s'écraser.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top