Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to efficiently select a subset of rows of a QTableView that match certain criteria?

I have a QTableView using a QSqlTableModel.

In the underlying database (postgresql) table there is a timestamp column.

How can I select all rows in the selection model where the underlying timestamp column is NULL?

Pointers in the right direction would help.

UPDATE:

The main issue I have been having is performance. Each method I have tried results in two performance issues.

The first is that the call to selectionModel()->select(selection) takes 30 seconds for about 5,000 selected records. It seems to be emitting the selection changed signal for each row. Even if the signal handlers are disabled it still takes 10 seconds.

The second performance issue is that even after the view is updated with the selected rows, trying to scroll the view is very slow and lags. My guess is that the selection model is made up of 5,000 individual selections rather than just the minimum number of selection ranges.

In the data that I am experimenting on the selection is contiguous; so it should be able to be represented as a single selection range. If I simply call tableView->selectAll(), then this is very fast.

What I was wondering is if there is a canonical, efficient way of selecting a bunch of matching rows. Or perhaps there is a flaw in my code that is causing the performance regression. Is there a way to use a QSortFilterProxyModel as suggested by count0 to accomplish this? I would like the view to display all rows, but have the matching ones selected.

Here is the code snippet for the last method that I tried:

void MainWindow::selectNullTimestamp()
{

    QModelIndex start = model->index(0, TIMESTAMP_COLUMN);


    QModelIndexList indexes = model
                ->match(start, Qt::DisplayRole,
            QVariant(QString("")),
            -1,
            Qt::MatchFixedString);

    QItemSelectionModel* selection_model = ui->tableView->selectionModel();

    QItemSelection selection;

    foreach(QModelIndex index, indexes) {

        QModelIndex left =
            model->index(index.row(), 0);

        QModelIndex right =
            model->index(index.row(),
                                 NUM_COLUMNS - 1);

        QItemSelection sel(left, right);

        selection.merge(sel, QItemSelectionModel::Select);

    }

    selection_model->select(selection, QItemSelectionModel::Select);

}
like image 429
Karl Voigtland Avatar asked Oct 14 '22 13:10

Karl Voigtland


1 Answers

May be too late, but it can always help! I faced this issue, and I think that using QItemSelection can efficiently solve the problem

Example:

assuming that your table view is called myTableView and you want to select even rows [0, 2, 4, 6, ...]

myTableView->clearSelection();
QItemSelection selection;
for (int i = 0 ; i < myTableView->rowCount(); i += 1)
{
    QModelIndex leftIndex  = myTableView->model()->index(i, 0);
    QModelIndex rightIndex = myTableView->model()->index(i, myTableView->columnCount() -1);

    QItemSelection rowSelection(leftIndex, rightIndex);
    selection.merge(rowSelection, QItemSelectionModel::Select);
}
myTableView->selectionModel()->select(selection, QItemSelectionModel::Select);
like image 111
Patrick Avatar answered Nov 15 '22 05:11

Patrick