سؤال

لقد كتبت الخاص بي QabstractItemModel لإظهار شجرة في TreeView. إنه يظهر عناصر المستوى الأعلى، ولكن عند توسيع دليل، يغلق التطبيق، تتم كتابة الرسالة التالية إلى وحدة التحكم: "خطأ تجزئة" ما أفعل الخطأ الذي يسبب هذا. فيما يلي نسخة مبسطة من التعليمات البرمجية الخاصة بي:

#!/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/tres., ، في ملف ليب / استعراض.

هل كانت مفيدة؟

المحلول 3

كانت المشكلة هي أنني أعود إلى مؤشر صالح للجذر في الأصل () عندما أعود إلى qtcore.qmodelindex ().

سيكون من الجيد أن تكون قادرا على تصحيح هذا النوع من الأشياء، والتي ما زلت لا أعرف كيف أفعل.

نصائح أخرى

استخدم الوحدة النمذجة. يمارس نموذجك لسيناريوهات مختلفة. يمكنك العثور عليه في / contrib / directory داخل حزمة التعليمات البرمجية المصدر PYQT.

هناك شيء يجري القمامة التي تم جمعها بواسطة Python التي لا تزال QT تريد استخدامها. هذه الأخطاء يصعب تتبعها. كخطوة أولى، أقترح إضافة هذا الخط قبل أو بعد setModel(model):

tree_view.model = model

سيوبح هذا مرجعا للنموذج في الجزء الثابت من كائن الشجرة.

إذا لم يساعد ذلك، فسيتعين عليك تجريد التعليمات البرمجية الخاصة بك حتى يتوقف عن التعطل.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top