リストビューにウィジェットを設定してから、カスタム プロキシフィルターを使用する必要があります。フィルターがないとうまく機能します。アクティブにすると、モデルに添付されているウィジェットが削除されるようです。
すべてのアイテムが正常に表示され、フィルタリングは機能しますが、フィルターを消去するときに、非表示のウィジェットを再度表示する必要がある場合、次のエラーがスローされます。
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