Details
-
Bug
-
Resolution: Done
-
P3: Somewhat important
-
4.7.3, 4.8.5
-
None
-
This was discovered using QtCreator with the MinGW compiler on Windows with Qt version 4.7.3
-
7bf4381a95bb4812f5a74419099a1a18f7a536a7 8fce4e97ba8479a24bff167ce72ed43223076905
Description
When the ItemIgnoresTransformations flag is set on a QGraphicsItem, the updates to the transforms eventually cascade into QGraphicsItemPrivate::updateSceneTransformFromParent(). In qgraphicsitem.cpp in the into QGraphicsItemPrivate::updateSceneTransformFromParent() method around line 1053 we see the following code:
else if (transformData->onlyTransform) { sceneTransform = transformData->transform; if (!pos.isNull()) sceneTransform *= QTransform::fromTranslate(pos.x(), pos.y()); sceneTransformTranslateOnly = (sceneTransform.type() <= QTransform::TxTranslate); }
As you can see, the sceneTransform is being set equal to the local transform! Then the translation due to the pos() is applied. I am 99% certain that this is incorrect. I believe the correct code should be:
else if (transformData->onlyTransform) { if (!pos.isNull()) sceneTransform *= QTransform::fromTranslate(pos.x(), pos.y()); else sceneTransform = QTransform(); sceneTransformTranslateOnly = (sceneTransform.type() <= QTransform::TxTranslate); }
With this new code, if a pos has been set then the sceneTransform is updated to account for that value. If no pos has been set, then the sceneTransform has no translation and is at 0,0 by setting it equal to a default QTransform. Now when the QGraphicsView uses deviceTransform() and deviceTransform() applies the transformations, it will have the correct transform instead of applying the translation of the local transform twice! (once in the transform and once in the sceneTransform)
Note, this bug was reported in version 4.6.3 at QTBUG-12105 and that bug was closed erroneously. The odd behavior which that individual was seeing, an odd shift when scaling, was due to this same issue. The odd shift was due to the local transform being erroneously set into the sceneTransform (because the ItemIgnoresTransformations was set). Then the erroneous scene transform was scaled by the view transform. (Actually I had this same issue in my code, my QGraphicsItems were experiencing an odd offset when setting the flag and scaling the view. That is what led me to investigate this issue.)
PLEASE DO NOT CLOSE THIS BUG WITHOUT LOOKING INTO IT SERIOUSLY. I HAVE ATTACHED A SIMPLE TEST PROJECT THAT ILLUSTRATES THE ISSUE. LOOK AT THE COMMENTS IN WIDGET.CPP. PLEASE E-MAIL ME IF YOU NEED FURTHER EXPLANATION OF THE ISSUE.