PDA

View Full Version : Question about QGraphicsItem and cache mode



di_zou
12th July 2010, 13:47
I have a class that inherits QGraphicsItem:


class DisplayItem(QGraphicsItem):
def __init__(self, parent):
self.setAcceptHoverEvents(True)
self.setFlag(QGraphicsItem.ItemIsMovable)
self.setFlag(QGraphicsItem.ItemIsSelectable)
self.setCacheMode(QGraphicsItem.DeviceCoordinateCa che)
def boundingRect(self):
adjust = 2.0
return QRectF(-10 - adjust, -10 - adjust, 23 + adjust, 23 + adjust)
def shape(self):
path = QPainterPath()
path.addEllipse(-10, -10, 20, 20)
return path
def paint(self, painter, option, widget):
painter.setPen(Qt.NoPen)
painter.setBrush(Qt.darkGray)
painter.drawEllipse(-7, -7, 20, 20)
gradient = QRadialGradient(-3, -3, 10)
color = QColor(QColor.fromHsv(60, 255, 255))
if self.isSelected():
color = QColor(Qt.white)
painter.setBrush(QBrush(color))
painter.setPen(QPen(Qt.black, 0))
painter.drawEllipse(-10, -10, 20, 20)
def mousePressEvent(self, event):
self.scene().clearSelection()
self.setSelected(True)

self.update()

self.bringToFront()

QGraphicsItem.mousePressEvent(self, event)

I have abunch of these QGraphicsItems in a QGraphicsScene displayed on screen through a QGraphicsView. The QGraphicsItem normally looks like a yellow circle with a black edge. When I click on the QGraphicsItem, it turns into a white circle with a black edge.
When I click on a different QGraphicsItem, the first item is supposed to revert back to being yellow and the new item is supposed to turn white. This does not happen. The old item stays white and the new item turns white.
However, if I comment out:

self.setCacheMode(QGraphicsItem.DeviceCoordinateCa che)
eevrything works the way it's supposed to. The new clicked on item turns white, and the old one turns back to yellow. I thought in this mode, the cache was regenerated everytime the item changes. So how come my items don't change?

tbscope
13th July 2010, 05:49
I thought in this mode, the cache was regenerated everytime the item changes. So how come my items don't change?

Well, yes, but clicking an item is not changing an item.

Quoting the documentation:

If the item is transformed directly or indirectly, the cache will be regenerated automatically.

Which makes sense since this type of caching is used for the best quality rendering (which is costly)

di_zou
13th July 2010, 15:55
So I guess changing the color isn't a transform? Is there any way to use this cache mode and do what I want it to do? ie update the chache everytime the color changes or everytime I click on it?

tbscope
13th July 2010, 18:25
So I guess changing the color isn't a transform?
No


Is there any way to use this cache mode and do what I want it to do? ie update the chache everytime the color changes or everytime I click on it?
Not with this cache mode, it is very specific (hence why it is fast). Use QGraphicsItem::ItemCoordinateCache or write your own cache.

wysota
13th July 2010, 21:04
I'm not sure you are correct. I think that calling update() on an item should invalidate the cache regardless of the mode. To me it seems the other item is simply not deselected (at least I don't see any code for that in the snippet above) and that's why it doesn't come back to its original state.