Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-21618

QGraphicsItem: sceneTransform being set equal to local transform when ItemIgnoresTransformations flag is set

    XMLWordPrintable

Details

    • Bug
    • Resolution: Done
    • P3: Somewhat important
    • 4.8.6, 5.1.1
    • 4.7.3, 4.8.5
    • Widgets: GraphicsView
    • 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.

      Attachments

        For Gerrit Dashboard: QTBUG-21618
        # Subject Branch Project Status CR V

        Activity

          People

            bibr Andreas Aardal Hanssen
            snowmane James Aaron Richards
            Votes:
            1 Vote for this issue
            Watchers:
            7 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes