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. Printing widgets not as bitmap, but in a vector based format
Forum Updated to NodeBB v4.3 + New Features

Printing widgets not as bitmap, but in a vector based format

Scheduled Pinned Locked Moved General and Desktop
17 Posts 6 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.
  • C Offline
    C Offline
    chronoss
    wrote on last edited by
    #1

    Hi there,

    I already searched a lot but didn't find anything of use about this topic, so I'd like to ask here.

    In my application I'd like to print a widget (a QTreeView, I don't think it matters).

    Based on an example I found I use the following code (PySide)

    [code]
    printer = QtGui.QPrinter(QtGui.QPrinter.HighResolution)
    printer.setOutputFileName("print.pdf")
    painter = QtGui.QPainter()
    painter.begin(printer)

    self.my_widget.render(painter, QtCore.QPoint())

    painter.end()
    [/code]

    Unfortunately, the PDF file is quite large, because it contains the widget as one big bitmap.

    Strangely, modifying the above code for usage with QSvgGenerator however:

    [code]
    printer = QtSvg.QSvgGenerator()
    printer.setFileName("print.svg")
    painter = QtGui.QPainter()
    painter.begin(printer)

    self.my_widget.render(painter, QtCore.QPoint())

    painter.end()
    [/code]

    ... yields a nice SVG drawing of my widget -- composed of separate SVG entities, no bitmaps at all.

    I also tried:

    • ... to read the produced SVG image and print it out again like above, using QSvgRenderer, but the produced PDF is rasterised, too.
    • Not using QPrinter::setOutputFilename() and "really" printing using a PDF renderer (FreePDF XP) also yielded a raster PDF file.
    • Printing the SVG out of inkscape using the same PDF printer produces a nice vector-based PDF file ...

    How can I configure or modify QPrinter to render the output vector based as well?

    Digging in the source code I found no real hints about this after over an hour -- the API is quite complex. So I hope anybody has experience with this and could point me in the right direction about how to set up or derive QPrinter so that it outputs vector data.

    Regards&thanks for your time,

    Björn

    1 Reply Last reply
    0
    • U Offline
      U Offline
      umundane
      wrote on last edited by
      #2

      I had the same question and found a solution. Posting here for anyone trying to figure out how to print QWidgets to a PDF as vectors and text.

      I did this in C++, but it should translate to Python roughly as follows:

      @
      // First render the widget to a QPicture, which stores QPainter commands.
      QPicture pic;
      QPainter picPainter(pic);
      self.my_widget.render(picPainter);
      picPainter.end();

      // Set up the printer
      printer = QtGui.QPrinter(QtGui.QPrinter.HighResolution)
      printer.setOutputFormat(QtGui.QPrinter.PdfFormat)
      printer.setOutputFileName("print.pdf")
      
      // Finally, draw the QPicture to your printer
      painter = QtGui.QPainter()
      painter.begin(printer)
      painter.drawPicture(QtCore.QPointF(0, 0), pic);
      painter.end()
      

      @

      The reason this extra step of drawing to a QPicture is necessary is that QWidget uses a different code path when printing to a printer than printing to any other QPaintDevice. For some reason it thinks you must want a bitmap if you're printing, so it renders to a QPixmap explicitly, then draws the pixmap to the painter. Rendering to a QPicture circumvents that behavior.

      I discovered this by looking through the Qt source code. I could not find any documentation describing this behavior.

      Hope that helps!

      I 1 Reply Last reply
      0
      • I Offline
        I Offline
        iskenderoguz
        wrote on last edited by
        #3

        Can you post c++ equilavent of this code. I try this but not work. I try to export a widget as pdf.

        @ QPicture pic;
        QPainter picPainter(pic);
        ui->widget->render(picPainter);
        picPainter.end();

            QPrinter printer(QPrinter::HighResolution);
            printer.setOutputFormat(QPrinter::PdfFormat);
            printer.setOutputFileName("12.pdf");
        
            QPainter paint();
            paint().begin(&printer);
            paint().drawPicture(0,20,pic);
            paint().end();
        

        @

        1 Reply Last reply
        0
        • I Offline
          I Offline
          iskenderoguz
          wrote on last edited by
          #4

          Can you post c++ equilavent of this code. I try this but not work. I try to export a widget as pdf.

          @ QPicture pic;
          QPainter picPainter(pic);
          ui->widget->render(picPainter);
          picPainter.end();

              QPrinter printer(QPrinter::HighResolution);
              printer.setOutputFormat(QPrinter::PdfFormat);
              printer.setOutputFileName("12.pdf");
          
              QPainter paint();
              paint().begin(&printer);
              paint().drawPicture(0,20,pic);
              paint().end();
          

          @

          1 Reply Last reply
          0
          • SGaistS Offline
            SGaistS Offline
            SGaist
            Lifetime Qt Champion
            wrote on last edited by
            #5

            Hi,

            No tested but it should rather be something like:

            @
            QPicture pic;
            QPainter picPainter(&pic);
            ui->widget->render(&picPainter);

            QPrinter printer(QPrinter::HighResolution);
            printer.setOutputFormat(QPrinter::PdfFormat);
            printer.setOutputFileName("12.pdf");

            QPainter painter(&printer);
            painter.drawPicture(0,20,pic);
            painter.end();
            @

            Interested in AI ? www.idiap.ch
            Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

            1 Reply Last reply
            0
            • SGaistS Offline
              SGaistS Offline
              SGaist
              Lifetime Qt Champion
              wrote on last edited by
              #6

              Hi,

              No tested but it should rather be something like:

              @
              QPicture pic;
              QPainter picPainter(&pic);
              ui->widget->render(&picPainter);

              QPrinter printer(QPrinter::HighResolution);
              printer.setOutputFormat(QPrinter::PdfFormat);
              printer.setOutputFileName("12.pdf");

              QPainter painter(&printer);
              painter.drawPicture(0,20,pic);
              painter.end();
              @

              Interested in AI ? www.idiap.ch
              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

              1 Reply Last reply
              0
              • I Offline
                I Offline
                iskenderoguz
                wrote on last edited by
                #7

                SGaist, your code works. but now pdf is empty white paper. nothing in it. I want to export my widget to pdf with high quality. I found another way to do this. but quality is low. There is some shapes in widget and these shapes look ugly with this code. How can I export my widget with high quality?

                Thank you and sorry for my English

                the code I found:

                @QPixmap pixmap;
                pixmap=QPixmap::grabWindow(ui->widget->winId());

                QPrinter printer(QPrinter::HighResolution);
                printer.setOrientation(QPrinter::Landscape);
                printer.setOutputFormat(QPrinter::PdfFormat);
                //printer.setPageMargins(10,10,10,10,QPrinter::Millimeter);

                printer.setOutputFileName("12.pdf");

                QPainter painter(&printer);
                QRect rect=painter.viewport();
                QSize size=pixmap.size();

                size.scale(rect.size(), Qt::KeepAspectRatio);
                painter.setViewport(rect.x(), rect.y(), size.width(), size.height());
                painter.setWindow(pixmap.rect());

                int pdfX=680-(640/20);
                int pdfY=460-(460/10);

                painter.drawText(0, 0, 640, 20, Qt::AlignHCenter, "graph");
                painter.drawPixmap(0, 20, pdfX, pdfY, pixmap);@

                1 Reply Last reply
                0
                • I Offline
                  I Offline
                  iskenderoguz
                  wrote on last edited by
                  #8

                  SGaist, your code works. but now pdf is empty white paper. nothing in it. I want to export my widget to pdf with high quality. I found another way to do this. but quality is low. There is some shapes in widget and these shapes look ugly with this code. How can I export my widget with high quality?

                  Thank you and sorry for my English

                  the code I found:

                  @QPixmap pixmap;
                  pixmap=QPixmap::grabWindow(ui->widget->winId());

                  QPrinter printer(QPrinter::HighResolution);
                  printer.setOrientation(QPrinter::Landscape);
                  printer.setOutputFormat(QPrinter::PdfFormat);
                  //printer.setPageMargins(10,10,10,10,QPrinter::Millimeter);

                  printer.setOutputFileName("12.pdf");

                  QPainter painter(&printer);
                  QRect rect=painter.viewport();
                  QSize size=pixmap.size();

                  size.scale(rect.size(), Qt::KeepAspectRatio);
                  painter.setViewport(rect.x(), rect.y(), size.width(), size.height());
                  painter.setWindow(pixmap.rect());

                  int pdfX=680-(640/20);
                  int pdfY=460-(460/10);

                  painter.drawText(0, 0, 640, 20, Qt::AlignHCenter, "graph");
                  painter.drawPixmap(0, 20, pdfX, pdfY, pixmap);@

                  1 Reply Last reply
                  0
                  • I Offline
                    I Offline
                    iskenderoguz
                    wrote on last edited by
                    #9

                    Also I tried to export Qimage to pdf but again quality is low.

                    @QPrinter printer;
                    printer.setOrientation(QPrinter::Portrait);
                    printer.setOutputFileName("test.pdf");
                    printer.setOutputFormat(QPrinter::PdfFormat);

                    QImage image("/home/asd/a.png");

                    QPainter painter;
                    painter.setRenderHint(QPainter::Antialiasing, true);
                    painter.begin(&image);
                    painter.end();

                    QPainter p;
                    p.begin(&printer);
                    p.drawImage(0, 0, image);
                    p.end();@

                    "http://www.qtcentre.org/threads/11236-2-questions-on-QPrint-QImage-PDF":http://www.qtcentre.org/threads/11236-2-questions-on-QPrint-QImage-PDF

                    1 Reply Last reply
                    0
                    • I Offline
                      I Offline
                      iskenderoguz
                      wrote on last edited by
                      #10

                      Also I tried to export Qimage to pdf but again quality is low.

                      @QPrinter printer;
                      printer.setOrientation(QPrinter::Portrait);
                      printer.setOutputFileName("test.pdf");
                      printer.setOutputFormat(QPrinter::PdfFormat);

                      QImage image("/home/asd/a.png");

                      QPainter painter;
                      painter.setRenderHint(QPainter::Antialiasing, true);
                      painter.begin(&image);
                      painter.end();

                      QPainter p;
                      p.begin(&printer);
                      p.drawImage(0, 0, image);
                      p.end();@

                      "http://www.qtcentre.org/threads/11236-2-questions-on-QPrint-QImage-PDF":http://www.qtcentre.org/threads/11236-2-questions-on-QPrint-QImage-PDF

                      1 Reply Last reply
                      0
                      • A Offline
                        A Offline
                        andre
                        wrote on last edited by
                        #11

                        Let's get clear on what you want to achieve, instead of on how you are doing it. Your code suggests that you are not just trying to print any widget, but specifically a graph widget. Is that correct?

                        1 Reply Last reply
                        0
                        • A Offline
                          A Offline
                          andre
                          wrote on last edited by
                          #12

                          Let's get clear on what you want to achieve, instead of on how you are doing it. Your code suggests that you are not just trying to print any widget, but specifically a graph widget. Is that correct?

                          1 Reply Last reply
                          0
                          • I Offline
                            I Offline
                            iskenderoguz
                            wrote on last edited by
                            #13

                            Andre, I have graphs (pie chart and "qcustomplot":http://www.qcustomplot.com/) and explanations(qlabel) in widget. I want to export these graphs and texts to pdf. codes which I used can export but quality is low. I want to export with high quality.

                            1 Reply Last reply
                            0
                            • I Offline
                              I Offline
                              iskenderoguz
                              wrote on last edited by
                              #14

                              Andre, I have graphs (pie chart and "qcustomplot":http://www.qcustomplot.com/) and explanations(qlabel) in widget. I want to export these graphs and texts to pdf. codes which I used can export but quality is low. I want to export with high quality.

                              1 Reply Last reply
                              0
                              • A Offline
                                A Offline
                                andre
                                wrote on last edited by
                                #15

                                I figured as much.

                                I've had similar issues last year. The solution I wend for is scaling up my rendering to match the output device. That really is the only way to get a good-looking result I found. That also means calculating a good font size for your items, and taking into account that some elements don't get too small (a hairline at 1200dpi will look really, really, really fine). I ended up having to deal with that on an element-by-element basis.

                                Note that you're dealing with about an order of magnitude higher resolutions than what you're getting on-screen.

                                Our printouts and PDF's look very crisp and clear now...

                                1 Reply Last reply
                                1
                                • A Offline
                                  A Offline
                                  andre
                                  wrote on last edited by
                                  #16

                                  I figured as much.

                                  I've had similar issues last year. The solution I wend for is scaling up my rendering to match the output device. That really is the only way to get a good-looking result I found. That also means calculating a good font size for your items, and taking into account that some elements don't get too small (a hairline at 1200dpi will look really, really, really fine). I ended up having to deal with that on an element-by-element basis.

                                  Note that you're dealing with about an order of magnitude higher resolutions than what you're getting on-screen.

                                  Our printouts and PDF's look very crisp and clear now...

                                  1 Reply Last reply
                                  0
                                  • U umundane

                                    I had the same question and found a solution. Posting here for anyone trying to figure out how to print QWidgets to a PDF as vectors and text.

                                    I did this in C++, but it should translate to Python roughly as follows:

                                    @
                                    // First render the widget to a QPicture, which stores QPainter commands.
                                    QPicture pic;
                                    QPainter picPainter(pic);
                                    self.my_widget.render(picPainter);
                                    picPainter.end();

                                    // Set up the printer
                                    printer = QtGui.QPrinter(QtGui.QPrinter.HighResolution)
                                    printer.setOutputFormat(QtGui.QPrinter.PdfFormat)
                                    printer.setOutputFileName("print.pdf")
                                    
                                    // Finally, draw the QPicture to your printer
                                    painter = QtGui.QPainter()
                                    painter.begin(printer)
                                    painter.drawPicture(QtCore.QPointF(0, 0), pic);
                                    painter.end()
                                    

                                    @

                                    The reason this extra step of drawing to a QPicture is necessary is that QWidget uses a different code path when printing to a printer than printing to any other QPaintDevice. For some reason it thinks you must want a bitmap if you're printing, so it renders to a QPixmap explicitly, then draws the pixmap to the painter. Rendering to a QPicture circumvents that behavior.

                                    I discovered this by looking through the Qt source code. I could not find any documentation describing this behavior.

                                    Hope that helps!

                                    I Offline
                                    I Offline
                                    ibrewster
                                    wrote on last edited by ibrewster
                                    #17

                                    @umundane
                                    I realize that this thread is really (really, really) old, but I just wanted to say that this remains an issue today eight years later, and this solution - render to a QImage then draw the image to the QPrinter - (still) works like a charm! Thanks!

                                    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