Last active
May 3, 2016 08:32
-
-
Save maty974/66e29df303d1f1825a53 to your computer and use it in GitHub Desktop.
QSortFilterProxyModel and QListView - indexWidget get deleted when filtering
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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_()) |
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
When filtering is active on the
QSortFilterProxyModel
, the viewindexWidget(index)
is like deleted or whatever append, I loose theQWidget
pointer....RuntimeError: Internal C++ object (PySide.QtGui.QLabel) already deleted.