QSortFilterProxyModel+QAbstractItemModelmodelIndex.internalPointer()导致撞车

2024-03-28 09:52:28 发布

您现在位置:Python中文网/ 问答频道 /正文

我在PyQt 4.8(python2.7)中实现了自己的qabstractemodel:

class FriendListModel(QtCore.QAbstractItemModel):
def __init__(self, groups, client):
    QtCore.QAbstractItemModel.__init__(self)
    self.root = groups
    self.client = client

    self.header = ['Player', 'Land', 'Rating', '#']

def columnCount(self, parent):
    return len(self.header);

def headerData(self, col, orientation, role):
    if orientation == QtCore.Qt.Horizontal and role == QtCore.Qt.DisplayRole:
        return self.header[col]
    return None

def rowCount(self, parentIndex):
    pointer = parentIndex.internalPointer()
    # if root level
    if pointer is None:
        return len(self.root)
    # if on FriendGroup level
    if hasattr(pointer, 'users'):
        return len(pointer.users)
    return 0

def index(self, row, column, parentIndex):
    pointer = parentIndex.internalPointer()
    # if root element, use root list
    if pointer is None:
        return self.createIndex(row, column, self.root[row])
    # if on FriendGroup level
    if hasattr(pointer, 'users'):
        return self.createIndex(row, column, pointer.users[row])
    return self.createIndex(row, column, None)

def data(self, index, role):
    if not index.isValid():
        return None
    pointer = index.internalPointer()
    if role == QtCore.Qt.DecorationRole and isinstance(pointer, User) and index.column() == 0:
        if pointer.avatarNotLoaded:
            pointer.loadPixmap()
            if not pointer.avatarNotLoaded:
                print 'loaded'
                self.emit(QtCore.SIGNAL('modelChanged'), index, index)
        return pointer.pix

    if role == QtCore.Qt.UserRole:
        if isinstance(pointer, FriendGroup):
            return None
        if index.column() == 0:
            return pointer.username

    if role == QtCore.Qt.DisplayRole or role == QtCore.Qt.UserRole:
        if isinstance(pointer, FriendGroup):
            if index.column() == 0:
                return pointer.name
            return None
        else:
            if index.column() == 1:
                return pointer.country
            if index.column() == 2:
                return pointer.rating
            if index.column() == 3:
                return '#'
            return pointer.name

    return None

def parent(self, index):
    if not index.isValid():
        return QtCore.QModelIndex()
    pointer = index.internalPointer()
    if hasattr(pointer, 'users'):
        return QtCore.QModelIndex()
    else:
        row = 0 if pointer.group == 'online' else 1
        return self.createIndex(row, 0, pointer.group)

在运行时,我向模型添加元素:

^{pr2}$

所有的看起来都是正确的(从ui),但是如果我试图从ModelIndex调用internalPointer,应用程序就会崩溃。 (应用程序崩溃,python.exe不再工作,没有stackstrace,…)

@QtCore.pyqtSlot(QtCore.QPoint)
def on_friendlist_customContextMenuRequested(self, pos):

    modelIndex = self.friendlist.indexAt(pos)
    if modelIndex == None or not modelIndex.isValid():
        return
    pointer = modelIndex.internalPointer()
    ...

我不知道我做错了什么。 有什么提示如何调试它?在

我搜索过类似的问题,但没有任何结果。在

编辑

如果我删除QSortFilterProxyModel,一切都正常。在

        #proxy = QtGui.QSortFilterProxyModel()
        #proxy.setSourceModel(self.model)
        #proxy.setSortRole(QtCore.Qt.UserRole)
        #self.friendlist.setModel(proxy)
        self.friendlist.setModel(self.model)

解决方案

我发现了我的错误。我使用了一个QSortFilterProxyModel,却忘了映射回去。在

@QtCore.pyqtSlot(QtCore.QPoint)
def on_friendlist_customContextMenuRequested(self, pos):

    modelIndex = self.friendlist.indexAt(pos)
    if modelIndex == None or not modelIndex.isValid():
        return
    pointer = self.proxy.mapToSource(modelIndex).internalPointer()
    if pointer == None:
        return
    playername = pointer.name
    print playername

https://github.com/IDragonfire/lobby/commit/6c49571f5619e85bb9cea76d84296f158ef81a9b

代码: https://github.com/IDragonfire/lobby/blob/d44ad39e7ce077918a18fe4aee4299b76a2b17b6/src/friendlist/friendlistdialog.py#L106


Tags: selfnoneindexreturnifdefcolumnqt