Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. [Solved] GraphicsView: Fixed line width regardless of transformations?
Forum Updated to NodeBB v4.3 + New Features

[Solved] GraphicsView: Fixed line width regardless of transformations?

Scheduled Pinned Locked Moved General and Desktop
2 Posts 1 Posters 915 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    Asperamanca
    wrote on last edited by
    #1

    I need to draw a line that is always exactly n pixels wide, regardless of any transformations applied.

    Cosmetic pens are not supported in GraphicsView (as can be seen in the comments to "QTBUG-5294":https://bugreports.qt-project.org/browse/QTBUG-5294 )

    How else to do this? I could calculate the necessary width once I get the transformation in the paint() method, but that would mean changing the boundingRect. Not something I'd like to do while painting.

    1 Reply Last reply
    0
    • A Offline
      A Offline
      Asperamanca
      wrote on last edited by
      #2

      This is how I do it now:

      • I calculate my effective non-cosmetic pen from the given pen plus the scene transform

      @ const qreal effectiveSourcePenWidth = qMax(sourcePen.widthF(),static_cast<qreal>(1.0));

      if ( ! sourcePen.isCosmetic())
      {
          QPen finalPen = sourcePen;
          finalPen.setWidthF(effectiveSourcePenWidth);
          return sourcePen;
      }
      
      QPointF scenePos = mapToScene(QPointF());
      const qreal halfPenWidth = effectiveSourcePenWidth / 2.0;
      QPointF edgeRight = mapFromScene(scenePos.x() + halfPenWidth,scenePos.y());
      
      QPen finalPen = sourcePen;
      finalPen.setCosmetic(false);
      finalPen.setWidthF(qAbs(edgeRight.x()));
      
      return finalPen;@
      
      • Based on that pen, I calculate my boundingRect

      @ if (m_eOrientation == Qt::Vertical)
      {
      m_CachedBoundingRect.setLeft(-effectiveHalfWidth);
      m_CachedBoundingRect.setRight(effectiveHalfWidth);
      m_CachedBoundingRect.setTop(-1000000.0);
      m_CachedBoundingRect.setBottom(1000000.0);
      }
      else
      {
      m_CachedBoundingRect.setTop(-effectiveHalfWidth);
      m_CachedBoundingRect.setBottom(effectiveHalfWidth);
      m_CachedBoundingRect.setLeft(-1000000.0);
      m_CachedBoundingRect.setRight(1000000.0);
      }

      m_CachedBoundingRectSceneTransform = sceneTransform();
      m_bCachedBoundingRectValid = true;@
      
      • I remember the sceneTransform I used, because whenever it changes, I need to recalculate pen and boundingRect. Now this is the tricky part, because I simply can't know about all cases where the sceneTransform changes. One thing I can recognize is if the transform of my own item changes:

      @ if (change == QGraphicsItem::ItemTransformHasChanged)
      {
      invalidateBoundingRectIfTransformChanged();
      }@

      • Otherwise I assume that any change to the sceneTransform must be followed by a paint(), so within paint() I do
        @ invalidateBoundingRectIfTransformChanged();
        updateBoundingRectAndPen();
        @

      Of course, this might trigger another paint. But after that, the sceneTransform should be stable.

      1 Reply Last reply
      0

      • Login

      • Login or register to search.
      • First post
        Last post
      0
      • Categories
      • Recent
      • Tags
      • Popular
      • Users
      • Groups
      • Search
      • Get Qt Extensions
      • Unsolved