[Solved] Problem with svg pictures and transparent background

  • Dear experts,

    I'm trying to code something which paints a widget using svg images. I have read that this is rather slow, and that the pictures have better to be pre-rendered first. I found this thread and thought that it would be straightforward to achieve what I wanted...
    My problem is that my pictures are diamond-shaped, and the QPixmap I use is of course rectangular. I want therefore the 4 corners of the QPixmap to be transparent, I have thus the following piece of code, mostly inspired from q8phantom's snippet:

    Converter -> load( fileName ); // Converter is a QSvgRenderer object pointer
    // checks that the loaded file is valid, extract the source size, etc.
    QPixmap image( destSize );
    QPainter painter( &image );
    Converter -> render( &painter );
    image.fill( Qt::transparent );

    In order to test that, I created a stupid little widget which displays 5 pictures converted from svg on a white background. The result shown here below, is clearly buggy to me, as there is this strange black background around the diamonds, background which even contains some text.
    Example picture
    I also checked that the obtained QPixmap is not transparent at all: if I put two diamonds with neighbouring edges, part of the one drawn first is hidden by the background from the second one.
    What am I missing?

    Some information: I'm using Qt 4.7.4 with gcc 4.6.1 on a 64 bit Mandriva 2011.

    Thanks in advance,

    Edit: I have the same strange behaviour using Qt 4.8.0 with gcc 4.6.2 on a 64 bit Fedora 16. I think the problem comes from the svg rendering: at some point I had a bug in my code and the svg was never rendered, which resulted in an "empty" QPixmap, i.e. totally transparent. As soon as I had the svg rendering, the background was buggy.

  • Hello guys!

    I can't believe nobody has a hint... Did I ask the question that shouldn't be asked? ;-)
    More seriously, I also investigated on my own in the meantime, but still no solution. If you miss any kind of information, please let me know.

    I put here a minimalist example :


    #include <QtGui/QWidget>
    class QPaintEvent;
    class Widget : public QWidget
        Widget(QWidget *parent = 0);
        void paintEvent(QPaintEvent *);
    #endif // BUGGYWIDGET_HPP


    #include "buggywidget.hpp"
    #include <QtGui/QPainter>
    #include <QtSvg/QSvgRenderer>
    #include <QtGui/QPixmap>
    Widget::Widget(QWidget *parent)
        : QWidget(parent)
        setPalette( QPalette( Qt::white ) );
        setGeometry( 0, 0, 800, 600 );
    void Widget::paintEvent(QPaintEvent *)
        QSvgRenderer * Converter = new QSvgRenderer( this );
        Converter -> load( QString( ":/VectorRedTile" ) );
        QPixmap image( 800, 240 );
        QPainter painter( &image );
        Converter -> render( &painter );
        image.fill( Qt::transparent );
        QPainter p( this );
        p.drawPixmap( 0, 180, image );


    #include <QtGui/QApplication>
    #include "buggywidget.hpp"
    int main(int argc, char *argv[])
        QApplication a(argc, argv);
        Q_INIT_RESOURCE( TestResources );
        Widget w;
        return a.exec&#40;&#41;;

    and BuggyTest.pro:

    # Project created by QtCreator 2012-03-13T07:27:52
    QT       += core gui svg
    TARGET = BuggyTest.exe
    TEMPLATE = app
    MOC_DIR = "./bin/moc/"
    OBJECTS_DIR = "./bin/objects/"
    DESTDIR = "./bin/"
    RESOURCES += TestResources.qrc
    SOURCES += main.cpp\
    HEADERS  += buggywidget.hpp

    With any svg file I use, the diamond is painted, now with a pure black background (I guess this background is just random). My problem is 100% reproducible with the given example.
    I see however something I didn't see before (maybe I just didn't notice it before): there's a warning message saying "QPixmap::fill: Cannot fill while pixmap is being painted on". Is this related to my problem?


    Edit: problem solved! I just had to write

    Pixmap image( 800, 240 );
    image.fill( Qt::transparent );
    QPainter painter( &image );
    Converter -> render( &painter );@
    instead of 
    @QPixmap image( 800, 240 );
    QPainter painter( &image );
    Converter -> render( &painter );
    image.fill( Qt::transparent );

    Sorry for the noise!

  • Moderators

    In your paintEvent() method, you should do the transparent fill before you do the painting.

    [Edit: I should finish reading your post before I write mine. I see you figured it out! :) ]

  • Thanks anyway!

Log in to reply

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.