Как сделать так, чтобы полоса прокрутки QListView сообщала правильное значение после обновления модели? - PullRequest
1 голос
/ 16 марта 2012

Я пытаюсь установить значение полосы прокрутки QListView сразу после обновления его модели. Проблема в том, что полоса прокрутки не настроена должным образом, поэтому ее значение maximum неверно. Это означает, что когда я устанавливаю значение, оно никогда не превысит этот (неправильный) максимум. Если я добавлю некоторые операторы qDebug в других местах, я увижу, что максимум снова вернется через некоторое время.

Полагаю, мне нужно каким-то образом принудительно обновить обновление полосы прокрутки или представления, но я пробовал разные вещи - updateGeometry, repaint, update, setFlow и т. Д., Но без успеха.

Любое предложение о том, что я мог бы сделать? Ниже мой текущий код:

int previousScrollValue = cardList_->verticalScrollBar()->value();

qDebug() << "Before" << previousScrollValue;

CardListModel* model = new CardListModel(deck->id());
cardList_->setModel(model); 
cardList_->verticalScrollBar()->setValue(previousScrollValue);

qDebug() << "After" << cardList_->verticalScrollBar()->value(); // Wrong value
qDebug() << "Max" << cardList_->verticalScrollBar()->maximum(); // Wrong value

Ответы [ 3 ]

0 голосов
/ 16 марта 2012

Вы пытались поставить QCoreApplication::processEvents() после setModel? I.e.:

CardListModel* model = new CardListModel(deck->id());
cardList_->setModel(model); 
QCoreApplication::processEvents();
cardList_->verticalScrollBar()->setValue(previousScrollValue);

qDebug() << "After" << cardList_->verticalScrollBar()->value(); // Wrong value
qDebug() << "Max" << cardList_->verticalScrollBar()->maximum(); // Wrong value

Я подозреваю, что обновление значений полосы прокрутки происходит только в цикле событий.

0 голосов
/ 16 марта 2012

После долгих проб и ошибок я наконец-то выяснил, что вызывало эту проблему:

У меня был установлен режим макета QListView Batched с размером 2x2.Я не уверен, почему у меня был этот набор, но я предполагаю, что это должно сделать дисплей более плавным, рендеринг партий элементов вместо всего за один раз.Проблема (я полагаю) заключается в том, что она портится с полосой прокрутки, которая постоянно обновляется по мере рендеринга пакетов, и она становится только в стабильном состоянии (с правильным максимумом и значением), когда все отображается.Только тогда имеет смысл вызывать setValue для него (но нет способа узнать, когда все элементы были обработаны).

Итак, исправление было простым - я просто отбросил layoutModeдо SinglePass и теперь полоса прокрутки работает как положено (и дисплей не заметно медленнее).Нет необходимости сохранять и восстанавливать значение полосы прокрутки, оно работает как есть.

0 голосов
/ 16 марта 2012

Я думаю, что updateGeometries - это функция, которую нужно вызвать.Если вы проверите реализацию функции scrollToBottom, то увидите, что эта функция называется:

void QAbstractItemView::scrollToBottom()
{
    Q_D(QAbstractItemView);
    if (d->delayedPendingLayout) {
        d->executePostedLayout();
        updateGeometries();
    }
    verticalScrollBar()->setValue(verticalScrollBar()->maximum());
}

Разница с updateGeometry заключается в том, что геометрия дочерних виджетов представлениябудет обновлен.

Если это не сработает, вы можете сделать:

cardList_->scrollToBottom();
qDebug() << "Max" << cardList_->verticalScrollBar()->maximum();
...