How To Refresh Qtableview When It Is Driven By Model
Solution 1:
For this purpose, you can use the QSortFilterProxyModel
class. This way, we don't tamper with the actual source model's structure or it's data. We just map the main source to this proxy model, which the view uses to display filtered/sorted data. We can affect the data in the proxy model as we please, without the risk of tampering the source model.
Here is your source code modified to use this:
import sys, os
from PyQt4 import QtCore, QtGui
app=QtGui.QApplication(sys.argv)
classTableModel(QtCore.QAbstractTableModel):
def__init__(self):
QtCore.QAbstractTableModel.__init__(self)
self.items=['One','Two','Three','Four','Five','Six','Seven']
defrowCount(self, parent=QtCore.QModelIndex()):
returnlen(self.items)
defcolumnCount(self, index=QtCore.QModelIndex()):
return1defdata(self, index, role):
ifnot index.isValid() ornot (0<=index.row()<len(self.items)):
return QtCore.QVariant()
item=str(self.items[index.row()])
if role==QtCore.Qt.DisplayRole:
return item
else:
return QtCore.QVariant()
classMySortFilterProxyModel(QtGui.QSortFilterProxyModel):
def__init__(self):
super(MySortFilterProxyModel, self).__init__()
self.cb_status=TruedefcbChanged(self, arg=None):
self.cb_status=arg
print self.cb_status
self.invalidateFilter()
deffilterAcceptsRow(self, sourceRow, sourceParent):
print_when_odd_flag = self.cb_status
is_odd = True
index = self.sourceModel().index(sourceRow, 0, sourceParent)
print"My Row Data: %s" % self.sourceModel().data(index, role=QtCore.Qt.DisplayRole)
if (sourceRow + 1) % 2 == 0:
is_odd = Falseif print_when_odd_flag:
if is_odd:
returnTrueelse:
returnFalseelse:
ifnot is_odd:
returnTrueelse:
returnFalseclassWindow(QtGui.QWidget):
def__init__(self):
super(Window, self).__init__()
mainLayout=QtGui.QHBoxLayout()
self.setLayout(mainLayout)
self.viewA=QtGui.QTableView()
self.viewA.horizontalHeader().setResizeMode(QtGui.QHeaderView.Stretch)
self.myModel=TableModel()
self.sortModel = MySortFilterProxyModel()
self.sortModel.setSourceModel(self.myModel)
self.viewA.setModel(self.sortModel)
self.checkBox=QtGui.QCheckBox("Show All")
self.checkBox.stateChanged.connect(self.sortModel.cbChanged)
self.checkBox.setChecked(self.sortModel.cb_status)
mainLayout.addWidget(self.viewA)
mainLayout.addWidget(self.checkBox)
self.show()
view=Window()
sys.exit(app.exec_())
As you can see, I have removed all connection from UI and the main source model. The main source model does not care about whether the checkbox is set or not. This keeps it decoupled. It's cleaner. The proxy model has been given this responsibility now. The filterAcceptsRow()
does the main heavy lifting of displaying the right row based on whether the index of the row shown is odd or even based on the checkbox status.
I have added a few print statements to it, just in case you want to alter the logic based on the data and not the index.
Check out the docs on QSortFilterProxyModel and some examples here.
Hope this was useful.
Post a Comment for "How To Refresh Qtableview When It Is Driven By Model"