2009-06-15 10 views
1

私は独自のQAbstractItemModelを作成して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に

答えて

0

問題は、QtCore.QModelIndex()を返す必要があるときにparent()のルートの有効なインデックスを返すことでした。

私はまだやり方がわからない、この種のものをデバッグすることができればいいです。

0

何かがゴミはまだPythonのどのQtので収集されています使いたいこれらのエラーは追跡が困難です。最初のステップとして、私はsetModel(model)前または後に次の行を追加することをお勧め:

tree_view.model = model 

これは、ツリーオブジェクトのPythonの一部でモデルの参照を保持します。

それでも問題が解決しない場合は、クラッシュを止めるまでコードを削除する必要があります。

1

modeltest.pyモジュールを使用してください! さまざまなシナリオでモデルを演習します。 PyQtソースコードパッケージ内の/ contrib /ディレクトリにあります。

関連する問題