Scroll QTableView as soon as model changes
-
I have a QTableView subclass that displays a QStandardItemModel subclass, I want to scroll to a certain row as soon as the model updates.
class OrderBook : public QStandardItemModel ... void OrderBook::updateModel() { std::pair<double, double> minMax = getMinMaxPrice(); if (minMax.first == -1 && minMax.second == -1) { setRowCount(0); return; } int numRows = calculateNumRows(minMax.first, minMax.second); setRowCount(numRows); resetCells(); setPrices(minMax.second); setOtherOrders(minMax.second); setOwnOrders(minMax.second); emit midPointChanged(calculateMidPoint()); } class OrderBookView : public QTableView ... void OrderBookView::onMidPointChanged(double midPoint) { //repaint(); size_t row = findClosestRow(midPoint); QModelIndex index = model()->index(row, 0); scrollTo(index, QAbstractItemView::ScrollHint::PositionAtCenter); }
The slots and signals are connected and the slot is called, the model also has the correct row count, but after rows were added it does not scroll the first time. It will scroll the second time the model is updated, probably because the rows are already displayed at that point, only their values change.
As you can see the ModelIndex is also valid. If I call repaint before scrolling, it works, but is it safe to do so? Are there better ways to do it?
-
@Herman-Nordberg
This is purely a guess, may make no difference, but worth a try?You seem to be using
setRowCount()
to increase/decrease the number of rows. (Following talks about removing rows; applies just as much to inserting rows.) Normally we callremoveRows()
, and through thatbeginRemoveRows()
and importantly therowsAboutToBeRemoved()
signal. I believe you will find views use that:Note: This function emits the rowsAboutToBeRemoved() signal which connected views (or proxies) must handle before the data is removed. Otherwise, the views may end up in an invalid state.
Does it make any difference to your view behaviour if you (at least temporarily) go via
removeRows()
, even if just to test? -
I have just tried it, but the behaviour is still the same.
After adding first row
After adding more rows, the rows are diplayed, but it doesn't scroll
After adding another order the row cout stays the same, and it scrolls
-
Hi,
Did you check that the index returned by findClosestRow is indeed valid ?
-
@SGaist said in Scroll QTableView as soon as model changes:
Hi,
Did you check that the index returned by findClosestRow is indeed valid ?
I have added a check now, yes it's valid.
-
And is it the index you are expecting ?
-
Yes, the model at that point has 100 rows and the midpoint is row 50, which is also the row in the ModelIndex.
-
For the sake of testing, can you use a queued connection ?
-
The same thing happens with a queued connection.
-
Which version of Qt are you running ?