在批处理模式下使用 QListWidget 时出现闪烁问题

Ton*_*vel 2 c++ qt qlistwidget

在批处理布局模式下使用QListWidget时,每当添加的项目数量超过批处理大小时,从旧列表切换到新列表时列表小部件会短暂闪烁。这意味着,列表小部件不显示任何项目,并且滚动条手柄设置为看似随机的大小。

请问您有遇到过这种情况吗,可以通过某种方式解决吗?我正在使用 Qt 4.7.4。我可能应该补充一点,我没有使用任何隐藏物品。

小智 6

我也遇到了这个问题,花了几个小时梳理 Qt 小部件渲染的海洋。最终,和你一样,我将问题追溯到QListView的批处理。看来,当启用批处理时,Qt 会触发内部计时器来执行底层滚动视图的增量布局调整。在这些增量布局期间,当滚动条可见时,更新区域无法正确计算(它太大并且不考虑滚动小部件本身占用的区域)。结果是一个错误的更新区域,随后会进入视口更新,这会带来不幸的副作用,即清除整个客户区域而不渲染任何 ListViewItems。

批处理完成后,最终的视口更新将正确计算布局几何图形(使用滚动条)并生成有效的更新区域;然后重新绘制列表中的可见元素。

随着列表中项目数量的增加(相对于批量大小),该行为会变得更糟。例如,如果您的列表从 500 个项目增长到 50000 个项目,并且批量大小为 50,则触发的“错误重绘”事件的数量会成比例增加,导致视图明显闪烁得更多。:(

这些增量(和失败)视口更新似乎也是导致您描述的滚动条手柄位置出现明显的混乱行为的原因。

这个问题的根源似乎与添加到 QListView::doItemsLayout() 中的“hack”有关,如下所述:

// 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);
Run Code Online (Sandbox Code Playgroud)

我想你可以重写 QListView::doItemsLayout() 并提供你自己的批处理来正确处理滚动条,但就我个人而言,我太老了,懒得清理别人的粪便。改用 SinglePass 完全解决了这个问题。无缝无闪烁渲染和滚动条行为是您所期待和喜爱的。耶。