PDA

View Full Version : [solved] Problems with QGraphicsSvgItem



grosem
17th June 2007, 15:53
Hi,

I want to use svg graphics in my QGraphicsView and so I found the QGraphicsSvgItem Class quickly.



QGraphicsSvgItem item(":/standard.svg");;
scene.addItem(&item);


It finds the file, but cannot load it:


Cannot open file ':/standard.svg', because: Unknown error

I created the svg file with inkscape so I thought it uses maybe a different svg syntax or something. So I used a svg of wikipedia, but had the same problem.

I use Qt 4.3.0.

Do you have an idea what I'm doing wrong?

EDIT: I forgot to mention: Same problem if I use a QSvgRenderer.

marcel
17th June 2007, 16:43
Are you sure you compiled the qrc?
What happens if you give the absolute path of the file instead the path in the resource system?

Put it somewhere accessible and give it a try.
Regards

grosem
17th June 2007, 17:58
ok, there were indeed some problems with the resource file.

Nevertheless I can't initialize the svg image directly:


QGraphicsSvgItem item(":/standard.svg");

no error and the place for the image is reserved, but I can't see the image.

It does work if I change the code to:


QSvgRenderer *renderer = new QSvgRenderer(QLatin1String(":boards/standard.svg"));
QGraphicsSvgItem *item = new QGraphicsSvgItem();


item->setSharedRenderer(renderer);

scene.addItem(item);

So do I really have to it this way? Can't I directly load the svg image?

Thanks for your help

marcel
17th June 2007, 18:10
From Assistant:



Detailed Description
The QGraphicsSvgItem class is a QGraphicsItem (http://www.qtcentre.org/forum/qgraphicsitem.html) that can be used to render the contents of SVG files.
QGraphicsSvgItem provides a way of rendering SVG files onto QGraphicsView (http://www.qtcentre.org/forum/qgraphicsview.html). QGraphicsSvgItem can be created by passing the SVG file to be rendered to its constructor or by explicit setting a shared QSvgRenderer (http://www.qtcentre.org/forum/qsvgrenderer.html) on it.
Note that setting QSvgRenderer (http://www.qtcentre.org/forum/qsvgrenderer.html) on a QGraphicsSvgItem doesn't make the item take ownership of the renderer, therefore if using setSharedRenderer (http://www.qtcentre.org/forum/qgraphicssvgitem.html#setSharedRenderer)() method one has to make sure that the lifetime of the QSvgRenderer (http://www.qtcentre.org/forum/qsvgrenderer.html) object will be at least as long as that of the QGraphicsSvgItem.
QGraphicsSvgItem provides a way of rendering only parts of the SVG files via the setElementId. If setElementId (http://www.qtcentre.org/forum/qgraphicssvgitem.html#setElementId)() method is called, only the SVG element (and its children) with the passed id will be renderer. This provides a convenient way of selectively rendering large SVG files that contain a number of discrete elements. For example the following code renders only jokers from a SVG file containing a whole card deck:
QSvgRenderer *renderer = new QSvgRenderer(QLatin1String("SvgCardDeck.svg"));
QGraphicsSvgItem *black = new QGraphicsSvgItem();
QGraphicsSvgItem *red = new QGraphicsSvgItem();
black->setSharedRenderer(renderer);
black->setElementId(QLatin1String("black_joker"));
red->setSharedRenderer(renderer);
red->setElementId(QLatin1String("red_joker"));
Size of the item can be set via the setSize() method or via direct manipulation of the items transformation matrix.
By default the SVG rendering is cached to speedup the display of items. Caching can be disabled by passing false to the setCachingEnabled (http://www.qtcentre.org/forum/qgraphicssvgitem.html#setCachingEnabled)() method.

As you can see, you need a renderer.
But you don't have to create the renderer every time( because it can be shared :) ).

I suggest making a singleton class in your app that is created just after QApplication. This will have only one member: a renderer.

Then, you can do something like:


QSvgRenderer renderer = SingletonClass::getInstance()->getSharedRenderer();


This way the renderer can be shared between multiple classes.

Another way is to make the renderer a member of your class.

Regards

grosem
17th June 2007, 19:27
Ok, next time I read the documentation more carefully.

And thanks for the hint :)

edit: just to clarify - I don't have to use the renderer if I just want to load the svg. I don't know why it worked before, but now it does (sounds quite confusing, I know...). Anyway, it works :)