PyQt QWidget в QAbstractListModel удаляется с помощью QSortFilterProxyModel

Мне нужно заполнить видовой список виджетами, а затем настроить собственный прокси-фильтр для работы с ним. Без фильтра он прекрасно работает, когда активен, кажется, удаляет виджеты, прикрепленные к модели.

Он хорошо показывает все элементы, фильтрация работает, но при удалении фильтра, когда скрытые виджеты должны быть показаны снова, появляется следующее сообщение об ошибке:

custom_widget.setGeometry (option.rect) RuntimeError: основной объект C/C++ был удален

Попытка не использовать QVariant и идти по маршруту internalPointer, но ломается в том же месте.

Спасибо, что посмотрели!

Настроить:

def __init__(self, *args): 
    QtGui.QWidget.__init__(self, *args) 

    # create temp data
    self.list_data = []
    for x in xrange(500):
        widget = ListItemWidget(text=str(x), parent=self)
        self.list_data.append((str(x), widget)) # testing to put in inmut tuple

    # create listviewmodel
    self.lm = ListViewModel(parent=self)

    # create listview widget
    self.lv = QtGui.QListView()

    # create filter proxy     
    self.proxy_model = ListViewFilterProxyModel()
    self.proxy_model.setFilterPattern('')
    self.proxy_model.setSourceModel(self.lm)

    # set model of listview to filter proxy
    self.lv.setModel(self.proxy_model)

    # set delegate for column 0
    self.lv.setItemDelegateForColumn(0, CustomWidgetDelegate(self.lv))

    self.lm.updateData(self.list_data)
    self.proxy_model.invalidate()

    self.connect(self.filter_edit, QtCore.SIGNAL("textChanged(QString)"), self.update_filter)

    def update_filter(self, pattern):
        self.proxy_model.setFilterPattern(pattern)
        self.proxy_model.invalidate()

Пользовательский виджет

class ListItemWidget(QtGui.QWidget):
    def __init__(self, text=None, parent=None):
        QtGui.QWidget.__init__(self)      
        self.text = text

    @QtCore.pyqtProperty(QtCore.QString)
    def text(self):
        return self.__text

    @text.setter
    def text(self, value):
        self.__text = value

Делегат для рисования зрения

    class CustomWidgetDelegate(QtGui.QItemDelegate):
        def __init__(self, parent=None):
            super(CustomWidgetDelegate, self).__init__(parent)

        def paint(self, painter, option, index):   
            custom_widget = index.model().data(index, QtCore.Qt.DisplayRole).toPyObject()[1]
>>>>>>      custom_widget.setGeometry(option.rect)
            if not self.parent().indexWidget(index):
                self.parent().setIndexWidget(index, custom_widget)

Модель представления списка:

class ListViewModel(QtCore.QAbstractListModel): 
    def __init__(self, parent=None, *args): 
        QtCore.QAbstractListModel.__init__(self, parent, *args)
        self.listdata = []

    def rowCount(self, parent=QtCore.QModelIndex()): 
        return len(self.listdata) 

    def data(self, index, role): 
        if role == QtCore.Qt.SizeHintRole:
            return QtCore.QSize(80, 80)
        if index.isValid() and role == QtCore.Qt.DisplayRole:
            return QtCore.QVariant(self.listdata[index.row()]).toPyObject()
        return QtCore.QVariant()    

    def updateData(self, listdata):
        self.listdata = listdata
        index = len(self.listdata)
        return True

Наконец, модель прокси фильтра:

class ListViewFilterProxyModel(QtGui.QSortFilterProxyModel):
    def __init__(self, parent=None):
        self.filter_str = None
        QtGui.QSortFilterProxyModel.__init__(self, parent)

    def setFilterPattern(self, pattern):
        self.filter_str = QtCore.QString(pattern)

    def filterAcceptsRow(self, sourceRow, sourceParent):
        if self.filter_str is None:
            return True
        index = self.sourceModel().index(sourceRow, 0, sourceParent)  
        # just testing on the str here...
        text = index.data().toPyObject()[0]
        if not str(self.filter_str) in text:
            return False
        return True

0 ответов

Другие вопросы по тегам