2

リストビューにウィジェットを設定してから、カスタム プロキシフィルターを使用する必要があります。フィルターがないとうまく機能します。アクティブにすると、モデルに添付されているウィジェットが削除されるようです。

すべてのアイテムが正常に表示され、フィルタリングは機能しますが、フィルターを消去するときに、非表示のウィジェットを再度表示する必要がある場合、次のエラーがスローされます。

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
4

0 に答える 0