【问题标题】:How to shift the pixels of part of a QGraphicsItem?如何移动部分 QGraphicsItem 的像素?
【发布时间】:2015-12-13 01:24:19
【问题描述】:

我想知道是否可以通过复制像素而不是重绘来移动绘图的一部分。

我在嵌入式环境中工作,其中性能是一个关键因素。我们使用 Qt 4.8。

我有一组要绘制的实时数据点。我定义了以下类:

class SetOfDataPoints : public QGraphicsItem
{
public:
  <constructor>
  QRectF boundingRect() const { ... }
  void paint(QPainter* painter,
             const QStyleOptionGraphicsItem* option,
             QWidget* widget = NULL) { ... }
  <other methods>
};

每隔一段时间,我读取一个新数据点,将其添加到SetOfDataPoints 的实例中,并将SetOfDataPoints 向左移动(通过在SetOfDataPoints 上调用QGraphicsItem::moveBy()),所以新数据点变得可见。结果,SetOfDataPoints::paint() 被调用,在该方法中我必须绘制 整个 数据点集。绘图目前仅包含连接数据点的线段,但未来会变得更加精细。

现在,重新绘制整个数据点集感觉效率很低,因为大多数图表实际上只是向左移动。我想将图形未更改部分的像素向左移动,并仅绘制连接最后两点的一条线段。至少我想尝试一下,并衡量这对性能的提升程度。

有没有办法在 Qt 4.8 中做到这一点?

【问题讨论】:

    标签: qt graphics qt4 pixel qgraphicsitem


    【解决方案1】:

    这通常不起作用:

    1. 在渲染之前,您的项目不会以任何像素的形式存在。您不知道它在多少像素上绘制,或者即使有,因为您的场景显示在 0 个或多个视图上,并且该项目可能在这些视图上以不同程度可见。

    2. 对您的项目应用了转换。它不一定是矩形的。

    3. 除非完全不透明,否则您的项目会与其下方的项目合成。

    4. 您的项目(显示在视图上)与视图所在小部件的后备存储组合在一起。

    您可以针对特殊情况进行优化。如果您的项目没有被缓存,那么它总是在视图上绘制,并且paint 的widget 参数将指向该小部件。然后,您可以直接访问后备存储,并且绘制程序会为您提供用于从项目坐标到后备存储设备坐标的转换。然后,您可以检查小部件树上从视图到窗口的路径是否不透明。如果所有介入的小部件都绘制为不透明的,并且您的项目具有保持方向的转换,那么您当然可以在图像上执行 blit,并仅重绘项目的一小部分。

    如果您的项目 被缓存,那么它应该被缓存在设备坐标中。当您在像素图上绘画时,您也可以进行 blitting。然后将该像素图合成到视图所在窗口的后备存储中。每个视图都有一个单独的缓存像素图。

    blitting 时,您必须始终识别之前的像素中有多少是正确的。对于每个视图或缓存像素图,您应该保留一个有效的区域。该区域最初应该是空的。

    【讨论】:

    • 正是这样的答案让 SO 成为了一个很棒的地方。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-08-14
    • 2012-07-19
    • 1970-01-01
    • 2012-06-19
    • 2014-02-20
    • 2021-08-03
    • 1970-01-01
    相关资源
    最近更新 更多