PDA

View Full Version : Vector graphics in Qt4



Abayo
5th August 2013, 22:18
Hi @ all!

I searched for a while now, but couldn´t find an answer to my problem.

I want to use vector graphics in a GUI. At first I tried to use QImage, but if I use the scaled() function my picture looks really bad..
I read now that there is a SVG format for vector graphics or (and?) I could use QPainter but I cannot see the connection.

Hopefully you all could give me a hint at using vector graphics :)

For the GUI I use a QGraphicsView with Scene where I put added some QGraphicsObjects classes I wrote myself.
I want to resize, transform, overlap different images to show some infos on the screen (like rotate an arrow over another background image).
The vector graphics are in a png format.

I hope it´s understandable what I mean :) (I am not so good in explaining myself, so sorry beforehand :p )

wysota
6th August 2013, 01:50
The vector graphics are in a png format.

No, they are not. PNG is a raster format, not a vector one.

Abayo
6th August 2013, 12:05
Ah ok, thx :)
I don´t know where I got the idea that png format is also for vector graphics.

So that means I should use svg-format?
Can you give me a hint at using svg in qt? (I search for myself of course (svg-viewer example), but more information is better and mybe someone knows a good trick )
Is it possible to use vector graphics like I was able to use the raster graphics with QImage? (QImage cannot display svg, so far I know)

Added after 1 7 minutes:

Pls have a look at this idea to use SVG and tell if it´s wrong:

In my program I use 3 classes (Speed, back, front). Each one is a QGraphicsObject.
In back and front I was setting my pictures and made some paintings.
In Speed I invoked back and front and set back as parent of front ( and Speed as parent of back). I also did some setPos() and rotate() commands in Speed for back and front.

Now, with QGraphicsSVGItem, I derive front and back from QGraphicsSVGItem and give the constructor the svg-file.
-> Do I now need an QSVGRenderer too? Documentation said that I can use renderer OR give svgfile to constructor.

Because QGraphicsSVGItem is a QGraphicsItem, I can use the painting methods from before and my Speed class is also not changing so much, right?

OR

should I use QGraphicsSVGItem like a QImage?
Then I would invoke in back instead of a QImage a QGraphicsSVGItem and use this for displaying the SVG-file

wysota
6th August 2013, 12:44
I don´t know where I got the idea that png format is also for vector graphics.
I do not know that either.


So that means I should use svg-format?
You can use whatever you like.


Can you give me a hint at using svg in qt? (I search for myself of course (svg-viewer example), but more information is better and mybe someone knows a good trick )
How do you intend to "use" it?


Is it possible to use vector graphics like I was able to use the raster graphics with QImage? (QImage cannot display svg, so far I know)
You can always rasterize an SVG image and use it with QImage.


-> Do I now need an QSVGRenderer too? Documentation said that I can use renderer OR give svgfile to constructor.
How about just try and see for yourself?


Because QGraphicsSVGItem is a QGraphicsItem, I can use the painting methods from before and my Speed class is also not changing so much, right?
I don't understand what you mean.


should I use QGraphicsSVGItem like a QImage?
I don't understand what you mean. The two have nothing in common. QImage is for accessing particular pixels of a raster image. Unless you want to change parts of the SVG drawing on the fly I don't see how would you want to "use QGraphicsSVGItem like a QImage".

Abayo
6th August 2013, 13:26
Yeah, I can see that you cannot understand what I mean :)
Think of myself as a noob with Svg in Qt and a beginner in Qt which tries to explain things with techniques he already learned ;)





So that means I should use svg-format?

You can use whatever you like.


Well.. that is true, but I wanted to know what kind of format would be the best for using vector graphics in Qt




How do you intend to "use" it?

=>

I want to resize, transform, overlap different images to show some infos on the screen (like rotate an arrow over another background image).

Imagine a class "front" with an arrow.svg (which is an arrow), a class"back" with a circle.svg (which is a circle) and a class "Speed".
Class "Speed" calls "back" and "front". "back" is a background-image and "front" is rotating happily in front of this background image.






Because QGraphicsSVGItem is a QGraphicsItem, I can use the painting methods from before and my Speed class is also not changing so much, right?
I don't understand what you mean.


I have read that QGraphicsSVGItem is derived from a QGraphicsItem. Up to this point "back", "front" and "Speed" were derived from this QGraphicsItem with a reimplemented paint() function to draw a QImage and to draw some other things (like text, and so on..).
My idea now was that I don´t derive "front" from QGraphicsItem, but instead from QGraphicsSvgItem. Then I could (in my theory) reimplement paint() again to draw my text. For the picture (the svg-file "arrow.svg") I was thinking about using



frontV = new Front(QString(QCoreApplication::applicationDirPath () + "/pictures/arrow.svg"),back); //invoke in Speed.cpp


insttead of



front = new Front_S(back); //invoke in Speed.cpp


Can you now understand my idea/theory about using svg in qt?





I don't understand what you mean. The two have nothing in common. QImage is for accessing particular pixels of a raster image. Unless you want to change parts of the SVG drawing on the fly I don't see how would you want to "use QGraphicsSVGItem like a QImage".

Yeah I think so too. And my question was misleading..
Until now I loaded a png-picture into a QImage with load() and displayed it inside a QGraphicsItem via drawImage() with a painter. With QImage I could use scaled() to resize the picture.
Now I want to display the SVG-file in my class and do some scaling/resizing.
For this I thought about using it "like QImage". Which meant calling inside my QGraphicsItem derived class "front" a new QGraphicsSvgItem and give this item the picture I desire.
I my opinion this way is similar to how I was using QImage before.


The question now is: Would that be a good way or the other way, where the class "front" is derived from QGraphicsSvgItem?




-> Do I now need an QSVGRenderer too? Documentation said that I can use renderer OR give svgfile to constructor.

How about just try and see for yourself?

Well, thanks for this advice.
I tried it and the program is crashing. So it looks like using QGraphicsSvgItem without QSVGRenderer is a bad idea.

wysota
6th August 2013, 14:46
I have read that QGraphicsSVGItem is derived from a QGraphicsItem. Up to this point "back", "front" and "Speed" were derived from this QGraphicsItem with a reimplemented paint() function to draw a QImage and to draw some other things (like text, and so on..).
My idea now was that I don´t derive "front" from QGraphicsItem, but instead from QGraphicsSvgItem. Then I could (in my theory) reimplement paint() again to draw my text.
Why not just instantiate QGraphicsSimpleTextItem and make it a child of the other item?


Can you now understand my idea/theory about using svg in qt?
SVG is not rocket science. In the end you end up with a raster image anyway. The difference from using QPixmap (using QImage doesn't really make any sense here) is that scaling quality is better.


I tried it and the program is crashing. So it looks like using QGraphicsSvgItem without QSVGRenderer is a bad idea.

There are many reasons why it could crash. The item has a default renderer, there is no point in overriding it unless you want to share the renderer with some other svg drawing.

Abayo
7th August 2013, 13:42
I already tested a bit with QGraphicsSimpleTextItem and QGraphicsTextItem but I couldn´t do what I wanted to do (mainly because of the missing alignment.. and the workaround for this was too much for only 2 numbers).
So I decided to write the numbers with the paint() method, because I already had to draw some lines.
-> Is it bad coding style to do it this way?

I found the reason why it crashed and both ways are working now. At the moment I use a QSvgRenderer, but I think I will switch back to the default renderer.
But one thing is still bothering me:
The graphics are looking good in big, but if I scale them down with factor 0.15 then I can see the pixels on diagonal lines. I think this happens because I converted the png format to svg format via inkscape, but could it also because Qt doesn´t use a resolution high enough?

wysota
7th August 2013, 14:41
-> Is it bad coding style to do it this way?
No.


I found the reason why it crashed and both ways are working now. At the moment I use a QSvgRenderer, but I think I will switch back to the default renderer.
The default renderer is also a QSvgRenderer. You substitute an object with identical one.


I think this happens because I converted the png format to svg format via inkscape, but could it also because Qt doesn´t use a resolution high enough?

http://www.qtcentre.org/attachment.php?attachmentid=6580&d=1308266944

Abayo
8th August 2013, 12:06
ok :)

Most of it is now clear, so for now thanks for your time and answers!
The rest I hope to find out myself.
Btw funny picture, but I cannot understand your answer ;)