wxTreeCtrl::SelectItem太慢了,该怎么办?
我有一个名为 newSelections 的wxArrayTreeItemIds,希望用它来选中treectrl中的对应项:
m_processingTreeSelect = true;
auto startTime = std::chrono::steady_clock::now();
_TRACE("STARTED");
m_sceneTreeViewCtrl->Freeze();
for (Uint32 i = 0u; i < newSelections.size(); ++i)
{
const wxTreeItemId& item = newSelections[i];
m_sceneTreeViewCtrl->SelectItem(item);
}
m_sceneTreeViewCtrl->Thaw();
const auto endTime = std::chrono::steady_clock::now();
const auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime).count();
_TRACE("DURATION(MS): " << duration);
为了防止死锁,我使用一个布尔变量m_processingTreeSelect:
m_sceneTreeViewCtrl->Bind(wxEVT_TREE_SEL_CHANGED, [&](){
if (m_processingTreeSelect)
return;
wxArrayTreeItemIds itemIds;
if (!m_sceneTreeViewCtrl->GetSelections(itemIds))
return;
m_processingTreeSelect = true;
// Build selection
Selection selection;
for (auto item : itemIds)
{
if (isRootItem(item))
continue;
switch (getSubRootType(item))
{
case TreeViewItemType::MeshGroup:
case TreeViewItemType::Light:
{
selection.m_entities.push_back(tryGetTreeItemIdentifier(item));
}
break;
default:
_ASSERT(false);
}
}
// Push selection change
beginSelectionChange(selection, false);
m_processingTreeSelect = false;
});
拥有一个包含10000个元素的数组时,下面这段代码执行需要大约三分钟。相反,如果用鼠标手动选中树中的所有项(Shift+左键单击),速度就很快!
我尝试了Freeze/Thaw的做法,它有点帮助,但还不够。
怎么办?
解决方案
你在执行时肯定应该冻结树,但一次性处理10000项在任何合理的场景下都太多。对于这类项数的树,通常会等到父节点展开后再对项进行任何操作(甚至包括把它们添加到树中),因此真正的修复办法是仅选择当前显示的项,等到 wxEVT_TREE_ITEM_EXPANDING 之后再选中父节点下的所有项。
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。