如何移动 QGraphicsItem 的一部分的像素?

How to shift the pixels of part of a QGraphicsItem?

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

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

我有一组实时数据点要绘制。我定义如下 class:

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

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

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

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

这通常不起作用:

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

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

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

  4. 显示在视图上的项目与视图所在的小部件的后备存储合成。

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

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

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