Проблема с миганием при использовании QListWidget в пакетном режиме

При использовании QListWidget в пакетном режиме компоновки всякий раз, когда добавляется больше элементов, чем размер пакета, виджет списка кратковременно мигает при переходе от старого списка к новому списку. Это означает, что в виджете списка нет элементов, а ручка полосы прокрутки имеет, казалось бы, случайный размер.

Вы когда-нибудь сталкивались с этим, можно ли это как-то решить? Я использую Qt 4.7.4. Я, вероятно, должен добавить, что я не использую никаких скрытых элементов.


person Ton van den Heuvel    schedule 05.05.2012    source источник


Ответы (1)


У меня тоже была эта проблема, и я часами прочесывал море рендеринга виджетов Qt. В конечном счете, как и вы, я проследил проблему до пакетной обработки QListView. Похоже, что когда пакетная обработка включена, Qt запускает внутренний таймер для выполнения дополнительных настроек макета базового представления прокрутки. Во время этих добавочных макетов, когда полоса прокрутки видна, область обновления вычисляется неправильно (она слишком велика и не учитывает области, занятые самими виджетами прокрутки). Результатом является плохая область обновления, которая впоследствии попадает в обновление окна просмотра, что имеет неприятный побочный эффект очистки всей клиентской области без рендеринга любого из ListViewItems.

После завершения пакетной обработки окончательное обновление окна просмотра правильно вычисляет геометрию макета (с полосой прокрутки) и создает действительную область обновления; затем видимые элементы в списке перерисовываются.

Поведение ухудшается по мере увеличения количества элементов в списке (относительно размера пакета). Например, если ваш список вырастет с 500 до 50000 элементов, а размер пакета будет равен 50, будет пропорционально увеличиваться количество событий "плохой перерисовки", которые вызывают еще большее заметное мерцание представления. :(

Эти добавочные (и неудачные) обновления области просмотра также, по-видимому, вызывают явное скачкообразное поведение в положении ручки полосы прокрутки, которое вы описываете.

Корень этой проблемы, по-видимому, связан с этим «взломом», который был добавлен в QListView::doItemsLayout(), как указано здесь:

// showing the scroll bars will trigger a resize event,
// so we set the state to expanding to avoid
// triggering another layout
QAbstractItemView::State oldState = state();
setState(ExpandingState);

Я полагаю, вы могли бы переопределить QListView::doItemsLayout() и предоставить свою собственную пакетную обработку, которая правильно обрабатывает полосы прокрутки, но лично я слишком стар и ленив, чтобы убирать чужие какашки. Переход на SinglePass полностью устранил проблему. Бесшовный рендеринг без мерцания и поведение полосы прокрутки, которое вы привыкли ожидать и любить. Ура.

person Jason Barlow    schedule 26.01.2013
comment
Спасибо, что раскопали первопричину этой проблемы! Когда у меня будет время и я не поленюсь, я отправлю отчет об ошибке :) - person Ton van den Heuvel; 27.01.2013