Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. [Solved] Problem with svg pictures and transparent background
Forum Updated to NodeBB v4.3 + New Features

[Solved] Problem with svg pictures and transparent background

Scheduled Pinned Locked Moved General and Desktop
4 Posts 2 Posters 10.9k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • JohanSoloJ Offline
    JohanSoloJ Offline
    JohanSolo
    wrote on last edited by JohanSolo
    #1

    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,
    Johan

    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.

    `They did not know it was impossible, so they did it.'
    -- Mark Twain

    1 Reply Last reply
    0
    • JohanSoloJ Offline
      JohanSoloJ Offline
      JohanSolo
      wrote on last edited by JohanSolo
      #2

      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 :

      buggywidget.hpp:

      #ifndef BUGGYWIDGET_HPP
      #define BUGGYWIDGET_HPP
      
      #include <QtGui/QWidget>
      
      class QPaintEvent;
      
      class Widget : public QWidget
      {
          Q_OBJECT
      
      public:
          Widget(QWidget *parent = 0);
          ~Widget();
          void paintEvent(QPaintEvent *);
      };
      
      #endif // BUGGYWIDGET_HPP
      

      buggywidget.cpp:

      #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 );
          update();
      }
      
      Widget::~Widget()
      {
      
      }
      
      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 );
      }
      

      main.cpp:

      #include <QtGui/QApplication>
      #include "buggywidget.hpp"
      
      int main(int argc, char *argv[])
      {
          QApplication a(argc, argv);
          Q_INIT_RESOURCE( TestResources );
          Widget w;
          w.show();
      
          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\
              buggywidget.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?

      Thanks,
      Johan

      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!

      `They did not know it was impossible, so they did it.'
      -- Mark Twain

      1 Reply Last reply
      0
      • M Offline
        M Offline
        mlong
        wrote on last edited by
        #3

        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! :) ]

        Software Engineer
        My views and opinions do not necessarily reflect those of anyone -- living or dead, real or fictional -- in this universe or any other similar multiverse node. Void where prohibited. Your mileage may vary. Caveat emptor.

        1 Reply Last reply
        0
        • JohanSoloJ Offline
          JohanSoloJ Offline
          JohanSolo
          wrote on last edited by
          #4

          Thanks anyway!

          `They did not know it was impossible, so they did it.'
          -- Mark Twain

          1 Reply Last reply
          0

          • Login

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • Users
          • Groups
          • Search
          • Get Qt Extensions
          • Unsolved