将Qt对象(QgraphicsItem)转换为C ++类对象的最佳方法是什么?

时间:2015-06-26 15:38:52

标签: c++ qt qgraphicsscene dynamic-cast

我正在尝试将Qt对象转换为像这样的循环中的C ++类对象

std::vector<PBWMPlugDeviceGraphicsItem*> deviceItms;

for(int i=0; i<fScene->items().size(); i++)
    deviceItms.push_back(dynamic_cast<PBWMPlugDeviceGraphicsItem*>(fScene->items().at(i)));

其中PBWMPlugDeviceGraphicsItem是C ++类。看来,当总没有。项目大于特定阈值(例如fScene->items().size() >900),转换这些对象需要相当长的时间,因此我可以看到QGraphicsScene上的操作非常慢。我读到dynamic_cast有严重的性能问题。

还有其他很好/快速的方法可以达到相同的效果吗?

谢谢!

4 个答案:

答案 0 :(得分:1)

使用此:

for (auto p: fScene->items())
    deviceItms.push_back(dynamic_cast<PBWMPlugDeviceGraphicsItem*>(p));

两个重要的区别:

  • 只拨打fScene->items()一次。除非该函数通过(const)引用返回,否则为每次迭代检索和丢弃容器都是无用的开销,特别是如果内容不应该在迭代之间发生变化。
  • 它不使用索引并在at()中验证该索引,而是使用带有自动类型变量的C ++ 11 for循环。 at()仅在您怀疑索引是否有效时才有用(例如,当它是来自用户的输入时),但如果您无法编写简单的循环,那么您确实有更重要的问题。

我没有采用vector::reserve()进行第三次优化来预先分配内存。如果你真的只有一些物体(是的,900只很少),那么它可能几乎不会引人注意。不过,做一些研究,因为它是你应该了解的工具。

答案 1 :(得分:1)

for(int i=0; i<fScene->items().size(); i++)
  deviceItms.push_back(dynamic_cast<PBWMPlugDeviceGraphicsItem*>(fScene->items().at(i)));

根据评论回复,似乎fScene->items()会返回QList<QGraphicsItem *>之类的内容。

在编写代码时,会在每次循环迭代时创建并丢弃此QList的实例。所以,作为第一次优化,我会尝试将 之外的获取,然后在循环中处理同一个实例,避免浪费列表的创建/销毁在每次循环迭代中。

如果您可以使用C ++ 11,我同意@ Ulrich建议使用基于范围的for循环:这将使代码更简单更快

修改

在这里的评论中你写道你不能使用C ++ 11,所以你不能享受基于范围的for循环。
然后,另一种选择可能是:

// Get the collection of items once, outside the loop
QList<QGraphicsItem *> items = fScene->items();

// For each graphics item in the collection...
for (int i = 0; i < items.size(); i++) {
    deviceItems.push_back(dynamic_cast<PBWMPlugDeviceGraphicsItem*>(items.at(i)));
}

答案 2 :(得分:0)

问题是调用QList::at,它返回对list item的引用,这会导致QList进行copy-on-write分离。

最小的解决方案是调用QList::value来获取指针,而不是at

其他解决方案是获取列表一次,如其他答案中所述。这样,即使您使用at,分离也只会发生一次。

您还可以通过强制转换或临时变量强制使用at的const版本。

答案 3 :(得分:0)

谢谢大家! 你的建议非常有用。我按照以下方式实现(因为我不能使用C ++ 11)

        QList<QGraphicsItem*> temp= fScene->items();
    for(int i=0; i<temp.size(); i++)
        deviceItms.push_back(dynamic_cast<PBWMPlugDeviceGraphicsItem*>(temp[i]));

它工作得很好。

非常感谢您提供有用的提示! 我真的学到了一些新的东西。