SPlatten SPlatten - 1 month ago 23
C++ Question

Qt Rotating text around its center point

I am using Qt 5.6, I want to draw a number of text labels around a circle and rotate the text labels to orientate the text according to its position around the circle, so 12 o'clock would have a 0 degree rotation, 3 o'clock would be rotated 90 degrees, 6 o'clock would be rotated 180 degrees etc.

I am aligning the text around its centre position:

void drawText(QPainter* pobjPainter, qreal fltX, qreal fltY
,int intFlags, const QString* pobjText) {
const qreal fltSize = 32767.0;

QPointF ptfCorner(fltX, fltY - fltSize);

if ( (intFlags & Qt::AlignHCenter) == Qt::AlignHCenter ) {
ptfCorner.rx() -= fltSize / 2.0;
} else if ( (intFlags & Qt::AlignRight) == Qt::AlignRight ) {
ptfCorner.rx() -= fltSize;
}
if ( (intFlags & Qt::AlignVCenter) == Qt::AlignVCenter ) {
ptfCorner.ry() += fltSize / 2.0;
} else if ( (intFlags & Qt::AlignTop) == Qt::AlignTop ) {
ptfCorner.ry() += fltSize;
}
QRectF rctPos(ptfCorner, QSizeF(fltSize, fltSize));
pobjPainter->drawText(rctPos, intFlags, *pobjText);
}


I would like to apply a rotation to the text.

I would like to reproduce something similar to what is shown:

http://www.informit.com/articles/article.aspx?p=1405545&seqNum=2

It seems that the rotate function rotates the entire painter canvas, so the coordinates must take into account the rotation which is really giving me a hard time. I want to position the text around the ellipse and then rotate it, how do I know what the coordinates should be?

Answer

Sticking with the clock example you could try something like...

virtual void paintEvent (QPaintEvent *event) override
  {
    QPainter painter(this);
    double radius = std::min(width(), height()) / 3;
    for (int i = 0; i < 12; ++i) {
      int numeral = i + 1;
      double radians = numeral * 2.0 * 3.141592654 / 12;

      /*
       * Calculate the position of the text centre as it would be required
       * in the absence of a transform.
       */
      QPoint pos = rect().center() + QPoint(radius * std::sin(radians), -radius * std::cos(radians));

      /*
       * Set up the transform.
       */
      QTransform t;
      t.translate(pos.x(), pos.y());
      t.rotateRadians(radians);
      painter.setTransform(t);

      /*
       * Specify a huge bounding rectangle centred at the origin.  The
       * transform should take care of position and orientation.
       */
      painter.drawText(QRect(-(INT_MAX / 2), -(INT_MAX / 2), INT_MAX, INT_MAX), Qt::AlignCenter, QString("%1").arg(numeral));
    }
  }