Tuesday, June 29, 2010

QGraphicsItem.itemChange event and ItemPositionChange in Qt 4.6

Recently, I had a bug in Robinviz that I could not figure out where it come from. I was drawing a graph and nodes could be moved. Whenever I moved the node, edges connected to it used to come with it to the new position. But after upgrading to Qt 4.6, I saw that edges were not moving.

After some investigation, I realized that QGraphicsItem.itemChange event did not produce QGraphicsItem.ItemPositionChange but only selected, deselected signals. Googling for it, I hardly found that the problem was with the update. Due to performance reasons, Qt developers decided to stop emitting geometrical signals and wanted us to switch it on by supplying a flag for the QGraphicsItem:


try:
# available only in Qt 4.6
self.setFlag( QGraphicsItem.ItemSendsGeometryChanges)
except:
# no need to do this in Qt 4.5
pass

You can do this flag option in your constructor. I used try/except because I didn't know what might happen in 4.5 as there was no flag called ItemSendsGeometryChanges. In some other websites, following flag was suggested but it did not work for me:

self.setFlag(QGraphicsItem.ItemSendsScenePositionChanges, True)


For those who might be interested how I used itemChanged, I'll provide a portion of my code:

def itemChange(self, change, value):
if change == QGraphicsItem.ItemPositionChange:
self.updateEdges()

return QVariant(value)