我有一个包含大约2500个自定义项目的列表。我用它们设置了它们:
const std::vector<const Items::AbstractItem *> results = _engine.request(text);
if (!results.empty())
{
for (auto i : results){
QListWidgetItem *lwi = new QListWidgetItem;
_results->addItem(lwi);
ListItemWidget *w = new ListItemWidget;
w->setName(i->name());
w->setTooltip(i->path());
_results->setItemWidget(lwi, w);
}
_results->setFixedHeight(std::min(5,_results->count()) * 48); // TODO
_results->show();
}
在i5-4590上大约需要5秒钟。隐藏窗口小部件的速度是原来的两倍。这是正常的还是我找错了?
答案 0 :(得分:3)
一些想法:
尝试为QWidgets分配正确的父级,这就是布局不必这样做 映射给你。这应该有助于提高绩效。
在开始插入之前调用setUpdatesEnable(false),在完成插入之后调用true
至于在添加大量项目时隐藏窗口小部件,这将有助于减轻无关的更新调用。上面的第二个建议可以减轻这一点。
答案 1 :(得分:2)
我认为这是完全预期的行为,例如Lists
或Trees
等不基于任何data model
的控件。我相信data model
的发明主要是为了解决这个问题。
在您的情况下,您有一个ListWidget
控件,可以自行存储数据。您需要在应用程序启动之前传递所有2500个项目,即使您的列表一次只显示10个项目,也需要执行此操作。即使您只是运行并关闭应用,用户也无法看到所有项目,但您仍需将其传递给ListWidget
。一些GUI框架使用项目的内部分配,在这种情况下,他们可以稍微优化一下,如果你在块中分配Items
但是它仍然不是一个好的解决方案,你也可以这样做。
现在让我们假设您介绍一些可能询问项目属性的对象。 Control
将询问某个项目,您的对象将回复内容。您的对象甚至不需要了解您的所有物品,只需在需要时学习。
你Control
可以询问几个第一项,当它意识到它可以填满整个高度时停止。这样您就可以避免现在不需要的工作。 Control
也可以询问项目计数,因此可以设置其垂直滑块。
需要说model
不会自动解决您的问题,它只是一种编程范式,可以让您做得更好。
因此,您的解决方案是使用QListView替换您的QListWidget,并实现您自己继承QAbstractListModel
的数据模型。您可以将results
传递给模型,并在需要时传递项目数据。
答案 2 :(得分:1)
如果您的QListWidgetItem
始终具有固定的尺寸,请拨打setUniformItemSizes
上的QListWidget
,然后传真。