tags:

views:

860

answers:

2

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);

}
A: 

In response to your code update, you could do without the loop if you use QAbstractItemView::SelectRows. Just use the selection you received from QAbstractItemModel::match().

As for speed, do check the efficiency of the table on a release build -- I know that debug/release build differences are big for cases like yours. If you're using Qt 4.5 you'll notice a speed-up too, as they did work to improve elements like tables in that release.

swongu
The QAbstractItemModel supports a function called match, it will do the searching for you, and returns a list of QModelIndex entries
Harald Scheirich
Cool, I've never used that function before but it seems to take care of the first point.
swongu
+1  A: 

Use QSortFilterProxyModel inbetween you model and the view.

count0
I would like to all of the rows to be displayed in the view, and have the matching rows selected. Will using the proxy model allow for this?
Karl Voigtland
Proxys can propagate the selection model, so a selection (selecting all) in a filtered model can be propagated into other views selecting only the desired column. QSortFilterProxyModel operates on one column so you would have to use a pipeline of them to get specific rows selected. I think it would be an elegant approach though.
count0
'...selecting only the desired column..' should be 'selecting only the desired rows..'
count0
Thanks. I'll give that a try next week.
Karl Voigtland