The posted code creates a singe Model/Proxy
QTableView
. The multi-selection feature has been enabled for it.
There are four items total. Two of them include a character "A". Other two include character "B" in their "item" names.
QPushButton
when pressed calls for the clicked()
method.
When called this method first queries a Proxy Model
connected to the QTableView
:
proxyModel=self.tableview.model()
Then the method asks a proxyModel
to return a total number of rows:
rows=proxyModel.rowCount()
Knowing how many rows in a QTabelView
's model it iterates each row. First it is querying a row index:
index=proxyModel.index(row, 0)
Knowing index
it proceeds with asking for a value stored in self.items
variable by calling data()
method supplying it with a queried in a previous step a QModelIndex
(a variable index
here) and a Role
flag.
item=proxyModel.data(index, Qt.DisplayRole).toPyObject()
'toPyObject()' is used to convert the data received from .data()
method to a "regular" Python variable.
Lastly it checks if the characters "B" in a received string. If so it selects QTableView row using:
self.tableview.selectRow(row)
Now what I want is to get the same selection functionality from inside of the scope of Proxy Model's filterAcceptsRow()
if that is possible.
If it is not possible I would like to know if there is any other way of doing it... should be I using QItemSelectionModel
? Then how?
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import sys
class Model(QAbstractTableModel):
def __init__(self, parent=None, *args):
QAbstractTableModel.__init__(self, parent, *args)
self.items = ['Item_A_001','Item_A_002','Item_B_001','Item_B_002']
def rowCount(self, parent=QModelIndex()):
return len(self.items)
def columnCount(self, parent=QModelIndex()):
return 1
def data(self, index, role):
if not index.isValid(): return QVariant()
elif role != Qt.DisplayRole:
return QVariant()
row=index.row()
if row<len(self.items):
return QVariant(self.items[row])
else:
return QVariant()
class Proxy(QSortFilterProxyModel):
def __init__(self):
super(Proxy, self).__init__()
def filterAcceptsRow(self, row, parent):
return True
class MyWindow(QWidget):
def __init__(self, *args):
QWidget.__init__(self, *args)
tableModel=Model(self)
proxyModel=Proxy()
proxyModel.setSourceModel(tableModel)
self.tableview=QTableView(self)
self.tableview.setModel(proxyModel)
self.tableview.horizontalHeader().setStretchLastSection(True)
self.tableview.setSelectionMode(QAbstractItemView.MultiSelection)
button=QPushButton(self)
button.setText('Select Items with B')
button.clicked.connect(self.clicked)
layout = QVBoxLayout(self)
layout.addWidget(self.tableview)
layout.addWidget(button)
self.setLayout(layout)
def clicked(self, arg):
proxyModel=self.tableview.model()
self.tableview.clearSelection()
rows=proxyModel.rowCount()
for row in range(rows):
index=proxyModel.index(row, 0)
item=proxyModel.data(index, Qt.DisplayRole).toPyObject()
if '_B_' in item:
self.tableview.selectRow(row)
if __name__ == "__main__":
app = QApplication(sys.argv)
w = MyWindow()
w.show()
sys.exit(app.exec_())