PDA

View Full Version : QGraphicsTextItem center based coordinates



mihnen
17th September 2012, 16:24
I'm trying to center a QGraphicsTextItem subclass inside of a parent rectangle however setPos() on this uses the top left corner for its origin. Is there some way to make a QGraphicsTextItem work on a center based coordinate system? I have searched google for hours and can't find any solutions. Any ideas would be appreciated.

d_stranz
18th September 2012, 02:35
It's just geometry.



// AlignedTextItem.h
#include <QGraphicsSimpleTextItem>

class AlignedTextItem
: public QGraphicsSimpleTextItem
{
public:
AlignedTextItem( const QString & text, Qt::Alignment flags, QGraphicsItem * pParent = 0 );
AlignedTextItem( const QString & text, QGraphicsItem * pParent = 0 );
AlignedTextItem( QGraphicsItem * pParent = 0 );

~AlignedTextItem();

QRectF boundingRect() const;
void paint( QPainter * pPainter, const QStyleOptionGraphicsItem * pOption, QWidget * pWidget = 0 );

Qt::Alignment alignment() const;
void setAlignment( Qt::Alignment flags );

private:
Qt::Alignment mFlags;
mutable QRectF mBounds;
};


// AlignedTextItem.cpp
#include "AlignedTextItem.h"
#include <QPainter>

AlignedTextItem::AlignedTextItem( const QString & text /*= QString()*/, Qt::Alignment flags /*= Qt::AlignTop | Qt::AlignLeft*/, QGraphicsItem * pParent /*= 0 */ )
: QGraphicsSimpleTextItem( text, pParent )
, mFlags( flags )
{
setFlag( ItemSendsGeometryChanges );
mBounds = QGraphicsSimpleTextItem::boundingRect();
}

AlignedTextItem::AlignedTextItem( const QString & text /*= QString()*/, QGraphicsItem * pParent /*= 0 */ )
: QGraphicsSimpleTextItem( text, pParent )
, mFlags( Qt::AlignTop | Qt::AlignLeft )
{
setFlag( ItemSendsGeometryChanges );
mBounds = QGraphicsSimpleTextItem::boundingRect();
}

AlignedTextItem::AlignedTextItem( QGraphicsItem * pParent /*= 0 */ )
: QGraphicsSimpleTextItem( pParent )
, mFlags( Qt::AlignTop | Qt::AlignLeft )
{
setFlag( ItemSendsGeometryChanges );
mBounds = QGraphicsSimpleTextItem::boundingRect();
}

AlignedTextItem::~AlignedTextItem()
{
}

Qt::Alignment AlignedTextItem::alignment() const
{
return mFlags;
}

void AlignedTextItem::setAlignment( Qt::Alignment flags )
{
mFlags = flags;
}

QRectF AlignedTextItem::boundingRect() const
{
mBounds = QGraphicsSimpleTextItem::boundingRect();
QPointF offset( 0.0, 0.0 );
if ( mFlags.testFlag( Qt::AlignRight ) )
offset.setX( -mBounds.width() );
else if ( mFlags.testFlag( Qt::AlignHCenter ) )
offset.setX( -mBounds.width() / 2.0 );

if ( mFlags.testFlag( Qt::AlignBottom ) )
offset.setY( mBounds.height() );
else if ( mFlags.testFlag( Qt::AlignVCenter ) )
offset.setY( mBounds.height() / 2.0 );

mBounds.translate( offset );
return mBounds;
}

void AlignedTextItem::paint( QPainter * pPainter, const QStyleOptionGraphicsItem * pOption, QWidget * pWidget /*= 0 */ )
{
pPainter->translate( mBounds.left(), -mBounds.top() );
QGraphicsSimpleTextItem::paint( pPainter, pOption, pWidget );
}

mihnen
18th September 2012, 19:20
Thanks for the reply, I like the idea of being able to change the origin point for the coordinates however it doesn't seem to work. I am using a QGraphicsTextItem which is editable and not a QGraphicsSimpleTextItem which you can only call setText() on. When I run the code with only change being to make it subclass from QGraphicsTextItem I get something looking like this:

8224

It seems as though whatever the base class call to paint() and boundingRect() is doing doesn't work with this?

d_stranz
19th September 2012, 16:48
Did you replace QGraphicsSimpleTextItem with QGraphicsTextItem in this code to create that screenshot, or is this what your own code is doing? Are you sure you have the signatures for all of the overridden methods correct (boundingRect() in particular)?

You might have to fire up the debugger and set a breakpoint on the paint() method to see exactly what happens in the base class.

Anyway, it looks to me as though the text in your screenshot has the correct horizontal centering, it is the vertical centering that is off. It is possible that the boundRect used by QGraphicsTextItem is computed differently from QGraphicsSimpleTextItem, and you may need to make some adjustments. QGraphicsTextItem uses a QTextDocument internally, and this document may have page formatting (like margins or indenting, for example) that are adding extra space that needs to be taken into account.