Important: Please read the Qt Code of Conduct -

How do I address individual elements in an SVG file?

  • Hi, I'm fairly new to Qt (a few months) and as usual I get chucked in at the deep end with a complex project to start with.

    I want to display an image containing a number of objects, each of which can be highlighted in a different colour on pressing a key. The whole image needs to scale as the window is resized.

    It seemed fairly obvious to look at doing it with SVG so that it can be scaled effectively. I've created a test image containing a set of objects each of which consists of one group. This displays and scales perfectly using resizeEvent() to calculate the new size and scale the image - so far so good.

    I decided the best way to highlight an individual object was to create duplicates of each group, give them separate IDs, and use setVisible() to toggle one on and the other off when the appropriate key is pressed.

    I'm now stuck on how to get this to work. The documentation for QGraphicsSvgItem is a start but it doesn't go far enough. I've sub-classed QGraphicsView and created a QGraphicsScene and I'm using setSharedRenderer() to share the renderer with all the objects, but what I can't work out is how to maintain control of the whole image (for scaling) while activating the individual objects. If I create a QGraphicsSvgItem for the whole image and add that to the scene, it displays and scales but I can't toggle the individual elements (each with its own QGraphicsSvgItem). If I add the elements to the scene as well, I can toggle them but they are displayed at about 4 times the size they should be and upside down. If I add the inner elements but not the outer whole image, the whole thing is over-scaled and upside down.

    So do I have to resize and rescale each individual element every time resizeEvent() is called or am I missing something? And if that's what I have to do, there doesn't seem much point in treating the whole image as a whole at all.

    Many thanks

  • Moderators

    I hope someone familiar with SVG pick it up, I don't have much experience with that module.

    QML seems to fit perfectly for your use case, but you've already chosen SVG - so be it. A few things to remember:

    • Qt implements SVG Tiny specifications, and there are some known bugs - but this module lacks a maintainer, they are not likely to be fixed. So it may well be that your code is OK, but Qt code isn't
    • SVG rendering is slow. Standard QGraphicsView, QPainter and QML are all faster

  • Thanks for your reply. I'm sure it's my code at fault, not Qt. This is not only my first Qt application, it's the first time I've used SVG. The scalable graphic is only a part of the UI and the rest of the UI and app has been built with C++, so at this stage I don't really want to be learning how to use QML as well! Speed of rendering isn't an issue as it's not a graphic-intensive app - the user will most likely scale the window once to the desired size and then leave it.

  • Not solved as such, but just to wrap up this thread, I've found an alternative way of doing what I want. If I dispense with the QGraphicsView and just use a QSvgWidget, storing the image in a QByteArray, I can manipulate the SVG elements in memory and just reload the data into the widget. It's actually a simpler way of achieving the samer result, though the speed of rendering seems even slower.

Log in to reply