Skip to content

Instantly share code, notes, and snippets.

@maty974
Last active May 3, 2016 08:32
Show Gist options
  • Save maty974/66e29df303d1f1825a53 to your computer and use it in GitHub Desktop.
Save maty974/66e29df303d1f1825a53 to your computer and use it in GitHub Desktop.
QSortFilterProxyModel and QListView - indexWidget get deleted when filtering
import PySide.QtGui as QtGui
import PySide.QtCore as QtCore
_DEFAULT_ITEM_SIZE = QtCore.QSize(100, 85)
_USER_ROLE = QtGui.QStandardItem.UserType + 1
class CustomItemWidget(QtGui.QWidget):
def __init__(self, parent=None):
super(CustomItemWidget, self).__init__(parent=parent)
self.setAutoFillBackground(True)
self.label_text = "None"
self.installEventFilter(self)
def eventFilter(self, obj, event):
if event.type() == QtCore.QEvent.Type.DeferredDelete:
print "QEvent.Type.DeferredDelete CustomItemWidget of:", self.label_text
return False
def paintEvent(self, event):
painter = QtGui.QPainter(self)
# Default brush and pen
bg_brush = QtGui.QBrush(QtGui.QColor("#8C8C8C"))
pen = QtCore.Qt.NoPen
painter.save()
painter.setPen(pen)
painter.setBrush(bg_brush)
painter.drawRoundedRect(self.rect(), 12, 12)
painter.restore()
# Paint the label text
painter.save()
painter.drawText(self.rect(), QtCore.Qt.AlignCenter, self.label_text)
painter.restore()
def setData(self, role, value):
if role == QtCore.Qt.DisplayRole:
self.label_text = value
class CustomItem(QtGui.QStandardItem):
def __init__(self):
super(CustomItem, self).__init__()
self.number = None
self.item_widget = CustomItemWidget()
def data(self, role):
if role == QtCore.Qt.DisplayRole:
value = "DATA %s" % str(self.number)
self.item_widget.setData(role, value)
return value
if role == QtCore.Qt.SizeHintRole:
return _DEFAULT_ITEM_SIZE
return QtGui.QStandardItem.data(self, role)
class CustomView(QtGui.QListView):
def __init__(self, parent=None):
super(CustomView, self).__init__(parent=parent)
self.setViewMode(QtGui.QListView.IconMode)
self.setResizeMode(QtGui.QListView.Adjust)
self.data_model = QtGui.QStandardItemModel()
self.proxy_model = QtGui.QSortFilterProxyModel(self.data_model)
self.proxy_model.setSourceModel(self.data_model)
self.setModel(self.proxy_model)
def logIndexWidgets(self):
print ""
for row in range(self.proxy_model.rowCount()):
index = self.proxy_model.index(row, 0)
print "\t", index.data(), self.indexWidget(index)
print ""
def keyPressEvent(self, event):
print "IndexWidgets BEFORE filtering:", self.logIndexWidgets()
if event.key() == QtCore.Qt.Key_1:
self.proxy_model.setFilterWildcard("*1*")
print "filtering by:", self.proxy_model.filterRegExp()
if event.key() == QtCore.Qt.Key_2:
self.proxy_model.setFilterWildcard("*2*")
print "filtering by:", self.proxy_model.filterRegExp()
if event.key() == QtCore.Qt.Key_3:
self.proxy_model.setFilterWildcard("*3*")
print "filtering by:", self.proxy_model.filterRegExp()
if event.key() == QtCore.Qt.Key_Backspace:
self.proxy_model.setFilterFixedString("")
print "filtering by:", self.proxy_model.filterRegExp()
print "IndexWidgets AFTER filtering:", self.logIndexWidgets()
QtGui.QListView.keyPressEvent(self, event)
def addItem(self, item):
self.data_model.appendRow(item)
proxy_index = self.proxy_model.mapFromSource(item.index())
self.setIndexWidget(proxy_index, item.item_widget)
if __name__ == '__main__':
import sys
qapplication = QtGui.QApplication(sys.argv)
layout = QtGui.QVBoxLayout()
window = QtGui.QDialog()
window.setLayout(layout)
view = CustomView(window)
view.resize(800, 600)
layout.addWidget(view)
for i in range(0, 10):
item = CustomItem()
item.number = i
view.addItem(item)
window.show()
sys.exit(qapplication.exec_())
@maty974
Copy link
Author

maty974 commented Jul 28, 2014

This is using PySide 1.2.1 on Linux with Python 2.7.5

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment