PDA

View Full Version : How to adjust the initial size of a QGraphicsSvgItem without using scale() ?



paradiza
23rd September 2007, 13:19
Hi all,

is there a way one can adjust the initial size of a QGraphicsSvgItem without using QGraphicsItem::scale(sx, sy)?

The problem is that I subsequently assign some children to this item which then inherit the transformation matrix of their parent, hence are also scaled. I need to set the initial size of my QGraphicsSvgItem before I assign its children and without changing their transformation matrices also.

FYI, I'm migrating from QGraphicsPixmapItems to QGraphicsSvgItems. Using QGraphicsPixmapItem I could just resize its pixmap before assigning it to the item. Thus the item's size reflected the size of the pixmap - a similar resizing doesn't seem to be possible with QSvgRenderer...


Thanks,
para

wysota
25th September 2007, 11:45
Seems that you are right. What you could do is to subclass the item and reimplement boundingRect(), shape() and paint() and introduce additional level of scaling there. This way it won't be propagated to children.

paradiza
25th September 2007, 12:35
Ok, that's what I presumed. No problem, I already subclassed QGraphicsSvgItem anyway...

Thanks mate!

Palmik
9th July 2010, 15:07
Hi, I know this is quite an old topic, but I needed the same functionality as paradiza. I noticed taht setSize() is mentioned in the docs here... http://doc.qt.nokia.com/4.6/qgraphicssvgitem.html#details but apparently it's some mistake, since QGraphicsSvgItem does not have setSize() member.

So... I have subclassed the QGraphicsSvgItem like this:
Header:

#ifndef MYSVGITEM_H
#define MYSVGITEM_H

#include <QGraphicsSvgItem>

class MySvgItem : public QGraphicsSvgItem
{
public:
MySvgItem(QGraphicsItem* parent = 0);
MySvgItem(const QString& fileName, QGraphicsItem* parent = 0);

//==================
// SETTERS & GETTERS
void setSize(QSizeF size);
/*inl*/ void setSize(qreal width, qreal height);
QSizeF size();

//================================================== ======
// REIMPLEMENTATION OF VIRTUAL METHODS OF QGRAPHICSSVGITEM
void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget = 0);
QRectF boundingRect();

private:
QSizeF size_m;
};

inline void MySvgItem::setSize(qreal width, qreal height) { setSize(QSizeF(width, height)); }

#endif // MYSVGITEM_H


Source:

#include "mysvgitem.h"
#include <QSvgRenderer>
#include <QStyleOptionGraphicsItem>

MySvgItem::MySvgItem(QGraphicsItem* parent)
: QGraphicsSvgItem(parent), size_m(-1.0, -1.0)
{
}

MySvgItem::MySvgItem(const QString& fileName, QGraphicsItem* parent)
: QGraphicsSvgItem(fileName, parent), size_m(-1.0, -1.0)
{
}

void MySvgItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
{
//QGraphicsSvgItem::paint(painter, option, widget);

Q_UNUSED(widget);
Q_UNUSED(option);

if (!renderer()->isValid())
return;

if (elementId().isEmpty())
renderer()->render(painter, boundingRect());
else
renderer()->render(painter, elementId(), boundingRect());
}

void MySvgItem::setSize(QSizeF size)
{
if (size_m != size) {
prepareGeometryChange();
size_m = size;
update(boundingRect());
}
}

QSizeF MySvgItem::size()
{
qreal width = size_m.width();
qreal height = size_m.height();

if (size_m.width() < 0) {
width = (renderer()->boundsOnElement(elementId()).size().width());
}

if (size_m.height() < 0) {
height = (renderer()->boundsOnElement(elementId()).size().width());
}

return QSizeF(width, height);
}

QRectF MySvgItem::boundingRect()
{
return QRectF(QPointF(0.0, 0.0), size());
}


It works great... but there seems to be one limitation. Create your custom *.svg file and some element and remember it's size. Now when you try to use MySvgItem::setSize(...) and you set the size bigger that what the dimensions of the element in the *.svg file are, then the item is not rendered as a whole, but just a part of it is rendered (at maximum size of the element).

So it looks like this:
http://filebeam.com/0fb6c68fc482a09bfbe5ddefc8283e2d.jpg

Setting the item's size up to the element's size works as it should.

Palmik
11th July 2010, 09:47
Hmm... it's probably some kind of bug in QSvgRenderer, for now I have "solved" the problem by having the elements extremely large in the *.svg file so that I can setSize to bigger numbers :/
Edit: Might it be this bug http://bugreports.qt.nokia.com/browse/QTBUG-5151 ? They seem to have rejected it because it's supposedly feature.