[PyQt] Selecting many rows in a QTableView
Thomas Robitaille
thomas.robitaille at gmail.com
Mon Aug 8 23:26:47 BST 2016
Hi everyone,
I am trying to create a QTableView in Qt which is efficient for large
tables. I've managed to make the display of data efficient by defining
my own abstract table model:
```
from PyQt4 import QtCore, QtGui
from PyQt4.QtCore import Qt
class DataTableModel(QtCore.QAbstractTableModel):
def columnCount(self, index=None):
return 3
def rowCount(self, index=None):
return 10000
def headerData(self, section, orientation, role):
if role != Qt.DisplayRole:
return None
if orientation == Qt.Horizontal:
return 'c'
elif orientation == Qt.Vertical:
return 'r'
def data(self, index, role):
if not index.isValid():
return None
if role == Qt.DisplayRole:
return "({0},{1})".format(index.row(), index.column())
app = QtGui.QApplication([""])
viewer = QtGui.QTableView()
model = DataTableModel()
viewer.setModel(model)
viewer.show()
```
This works fine, because the data method is only called for cells that
appear in the field of view of the table.
I now want to display an existing selection of some fraction of the rows:
```
import numpy as np
selected_rows = np.where(np.random.random(10000) > 0.5)[0]
```
I can tell the table widget about this selection by doing e.g.:
```
smodel = viewer.selectionModel()
for row in selected_rows:
model_index = model.createIndex(row, 0)
smodel.select(model_index, QtGui.QItemSelectionModel.Select |
QtGui.QItemSelectionModel.Rows)
```
However, this is very inefficient. It typically takes a second to
select 1000-2000 rows, when in practice I have tables with millions of
rows. There may be ways of speeding up this loop, but I would like to
do away with the loop altogether, and instead have Qt only ask me
(similarly to the data itself) for information about selections within
the visible cells (similar to what happens with the data model). Is
this possible, and if so, what is the best way to achieve this?
I asked this question on StackOverflow [1] - the two solutions
suggested there are:
- Build up a QItemSelection and select rows at the last minute: this
is not a good solution in my case because it's still slow.
- Create a custom item selection model: this doesn't seem to work
because non-virtual methods such as isSelected can't be overridden.
Does anyone here have any other suggestions for how to achieve this?
Thanks,
Tom
[1] http://stackoverflow.com/questions/38829929/selecting-many-rows-in-qt-table
More information about the PyQt
mailing list