QGraphicsItem中的ItemCoordinateCache和DeviceCoordinateCache有什么区别?

What is the difference between ItemCoordinateCache and DeviceCoordinateCache in QGraphicsItem?

我已经阅读了关于它们的文档,但我仍然不清楚实际的区别是什么。 ItemCoordinateCache 的文档说明:

Caching is enabled for the item's logical (local) coordinate system.

而 QGraphicsItem::DeviceCoordinateCache:

Caching is enabled at the paint device level, in device coordinates. This mode is for items that can move, but are not rotated, scaled or sheared.

这并没有为我解决问题。好的,所以 DeviceCoordinateCache 不能用于旋转、缩放或剪切,它使用 "device coordinates"。

但这到底是什么意思呢?有一个屏幕外缓冲区,我假设对于本地坐标,缓冲区充满了项目的缓存图像,然后像 QGraphicsPixmapItem 一样工作,并且应用了不透明度和变换矩阵等任何效果。我认为问题在于这会栅格化项目的图像,所以这就是文档警告它不会像素完美的原因。

但是它如何与 DeviceCoordinateCache 一起工作?项目是先旋转、剪切和缩放然后绘制在屏幕外的像素图上,还是它在像素图上呈现相同但没有应用任何转换?

编辑: 我还尝试将 DeviceCoordinateCache 设置为旋转和缩放的项目,它显示完美,即使我调整了它的大小,所以我不明白为什么文档这么说不应与缩放、旋转或剪切的项目一起使用。

物品坐标缓存

There is an off-screen buffer, and I assume for local coordinates the buffer is filled with the item's cached image, and then acts like a QGraphicsPixmapItem and any effects such as opacity and the transform matrix are applied to it. I assume the problem is that this rasterizes the item's image so that's why the docs warn that it won't be pixel-perfect.

没错。缓存以您使用 setCacheMode() 指定的质量存储在内存中。后续转换不会使缓存失效,它会被重用,这就是质量会下降的原因。如果它恶化太多,您可以通过再次调用 setCacheMode() 以更大的大小使缓存无效。


设备坐标缓存

But how does it work with a DeviceCoordinateCache? Is the item first rotated, sheared and scaled and then painted on the off-screen pixmap

再一次,您做对了:应用转换,然后将结果直接缓存在设备内存中。缓存始终以最高质量执行。但是,除了移动之外的任何新转换都会使缓存无效,这使我们想到了您最后的话:

Also I tried setting DeviceCoordinateCache to a rotated and scaled item and it displayed perfectly, even when I resized it, so I don't understand why the docs say it shouldn't be used with scaled, rotated or sheared items.

除移动之外的任何新转换都会使缓存失效。它仍然有效,并且始终可以完美显示,但效率不高:每次调整大小时都会强制使用新的缓存。


TL;DR

如果您不一直变换项目,请使用 DeviceCoordinateCache。如果这样做,请使用 ItemCoordinateCache 或根本不使用任何缓存。

  • 使用 DeviceCoordinateCache,缓存将始终是像素完美的,但会随着每次转换而失效。
  • 使用 ItemCoordinateCache,缓存不会因每次转换而失效,但结果不会是像素完美的。