PyQt QWidget in QAbstractListModel gets deleted with QSortFilterProxyModel

99封情书 提交于 2019-12-08 02:03:51

问题


I need to populate a listview with widgets, then have a custom proxyfilter work with it. Without the filter it works great, when active it seems to delete the widgets attach to the model.

It shows up fine showing all items, filtering works but when erasing the filter, when hidden widgets should be shown again following error gets thrown:

custom_widget.setGeometry(option.rect) RuntimeError: underlying C/C++ object has been deleted

Tried not using QVariant and going the internalPointer route but breaks at the same spot.

Thanks for having a look!

Setup:

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()

Custom widget

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

Delegate for painting the view

    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)

List view model:

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

Finally the filter proxy model:

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

来源:https://stackoverflow.com/questions/17854877/pyqt-qwidget-in-qabstractlistmodel-gets-deleted-with-qsortfilterproxymodel

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!