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. HiDPI and SVG icon resolution
Forum Update on Monday, May 27th 2025

HiDPI and SVG icon resolution

Scheduled Pinned Locked Moved Solved General and Desktop
svgiconshidpiresolution
24 Posts 4 Posters 9.4k Views
  • 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.
  • M Offline
    M Offline
    mrjj
    Lifetime Qt Champion
    wrote on 29 Oct 2019, 13:38 last edited by mrjj
    #2

    Hi
    If using the SVG via QIcon, i noticed something.
    It would not scale the SVG above the page rect ( ViewBox)
    of the SVG.
    It would then show as your image. ( pixelated)

    So try open
    waves-24px.svg
    in say InkScape and scale the svg to much bigger, like 512x512 and select
    via the Document Properties "Resize page to drawing or selection" button.

    Then rerun sample and see.

    Update:
    Oh. icon is there. :)
    The view box is currently 20x16 so it wont scale above that.
    Try this one
    https://www.dropbox.com/s/epbbn6xxslgpkj3/waves-24px.svg?dl=0
    i changed to 512x512
    (since it vector, it wont make file bigger or anything else)
    Its just a bigger viewBox.

    1 Reply Last reply
    0
    • C Offline
      C Offline
      cle1109
      wrote on 29 Oct 2019, 13:47 last edited by
      #3

      Thanks @mrjj, but unfortunately using your modified icon doesn't solve the issue - the icon looks exactly the same as the original one. I also tried to scale it up to 2400x2400 in Inkscape, but this doesn't change anything in the app either.

      M 1 Reply Last reply 29 Oct 2019, 14:08
      0
      • C cle1109
        29 Oct 2019, 13:47

        Thanks @mrjj, but unfortunately using your modified icon doesn't solve the issue - the icon looks exactly the same as the original one. I also tried to scale it up to 2400x2400 in Inkscape, but this doesn't change anything in the app either.

        M Offline
        M Offline
        mrjj
        Lifetime Qt Champion
        wrote on 29 Oct 2019, 14:08 last edited by
        #4

        @cle1109
        Ok, thank you for testing.
        It was worth a shot but its clearly related to HI-DPI then.
        Sadly i have no 4k screen to test on. I wish i had. ;)

        Oh. should have looked at SO. Sorry. excactly same was discussed there.

        But seems that was not it. In this case.

        1 Reply Last reply
        0
        • C Offline
          C Offline
          cle1109
          wrote on 29 Oct 2019, 14:15 last edited by
          #5

          Thanks for your input, I really appreciate it. I'm starting to think that this might be a Qt bug (maybe specific to macOS).

          M 1 Reply Last reply 29 Oct 2019, 14:18
          0
          • C cle1109
            29 Oct 2019, 14:15

            Thanks for your input, I really appreciate it. I'm starting to think that this might be a Qt bug (maybe specific to macOS).

            M Offline
            M Offline
            mrjj
            Lifetime Qt Champion
            wrote on 29 Oct 2019, 14:18 last edited by
            #6

            @cle1109
            hi, you are most welcome. Wish i had a working answer.
            i can only say on linux and windows, it did work for me on 1440p screens.
            But if 4k is more special or its due to/only on MacOS, i dont know.

            1 Reply Last reply
            0
            • S Offline
              S Offline
              SimonSchroeder
              wrote on 30 Oct 2019, 07:53 last edited by
              #7

              The problem might be that you leave it to Qt to render the SVG to pixels. What you can try instead is rendering the SVG into a QPixmap first and set this for the icon. Something similar to this (untested code, C++):

              MainWindow *mw = ...
              QToolbar *toolbar = ...
              ...
              QImage svgImage(""waves-24px.svg"");
              QPixmap svgPixmap(toolbar->iconSize());
              svgPixmap->setDevicePixelRatio(mw->pixelRatio());
              QPainter painter;
              painter.begin(&svgPixmap);
              painter.drawImage(0,0,svgImage);
              painter.end();
              QIcon icon(svgPixmap);
              QAction *action = new QAction(icon, "Test");
              toolbar->addAction(action);
              ...
              

              Maybe, you'll even need a larger pixmap:

              QPixmap svgPixmap(toolbar->iconSize() * mw->pixelRatio());
              

              As you can see, I am calling pixelRatio() on the MainWindow. The reason behind this is that with multiple monitors of different sizes and resolutions it is possible to have a different pixelRatio per screen (at least on Windows). This has extra problems if you move the widget from one screen to the other...

              1 Reply Last reply
              0
              • C Offline
                C Offline
                cle1109
                wrote on 30 Oct 2019, 08:23 last edited by
                #8

                Thanks @SimonSchroeder, I've translated the code to Python as follows:

                import sys
                from PyQt5.QtWidgets import QApplication, QMainWindow, QAction
                from PyQt5.QtGui import QIcon, QImage, QPixmap, QPainter
                
                
                app = QApplication(sys.argv)
                main = QMainWindow()
                toolbar = main.addToolBar("toolbar")
                image = QImage("waves-24px.svg")
                pixmap = QPixmap(toolbar.iconSize())
                pixmap.setDevicePixelRatio(main.devicePixelRatio())
                painter = QPainter()
                painter.begin(pixmap)
                painter.drawImage(0, 0, image)
                painter.end()
                icon = QIcon(pixmap)
                action = QAction(icon, "Test")
                toolbar.addAction(action)
                toolbar.show()
                main.show()
                sys.exit(app.exec_())
                

                Note that a QMainWindow doesn't have a pixelRatio method so I've replaced that with a call to devicePixelRatio.

                However, there seems to be something wrong because the result looks like this:

                Screen Shot 2019-10-30 at 09.17.26.png

                The actual content of the icon changes with each program execution BTW.

                On a related note, I found out that this is indeed a macOS-specific issue, because everything looks fine on Linux and Windows using the same 4K monitor in scaled mode (I'm using the original code snippet from my initial post):

                hidpi_linux.png
                hidpi_windows.png

                I guess this is indeed a Qt bug then and I'll report it. Still, I'd be interested in getting the workaround using QPixmap to actually work - then I could use that on macOS until they've fixed the underlying issue.

                J S 2 Replies Last reply 30 Oct 2019, 08:42
                0
                • C cle1109
                  30 Oct 2019, 08:23

                  Thanks @SimonSchroeder, I've translated the code to Python as follows:

                  import sys
                  from PyQt5.QtWidgets import QApplication, QMainWindow, QAction
                  from PyQt5.QtGui import QIcon, QImage, QPixmap, QPainter
                  
                  
                  app = QApplication(sys.argv)
                  main = QMainWindow()
                  toolbar = main.addToolBar("toolbar")
                  image = QImage("waves-24px.svg")
                  pixmap = QPixmap(toolbar.iconSize())
                  pixmap.setDevicePixelRatio(main.devicePixelRatio())
                  painter = QPainter()
                  painter.begin(pixmap)
                  painter.drawImage(0, 0, image)
                  painter.end()
                  icon = QIcon(pixmap)
                  action = QAction(icon, "Test")
                  toolbar.addAction(action)
                  toolbar.show()
                  main.show()
                  sys.exit(app.exec_())
                  

                  Note that a QMainWindow doesn't have a pixelRatio method so I've replaced that with a call to devicePixelRatio.

                  However, there seems to be something wrong because the result looks like this:

                  Screen Shot 2019-10-30 at 09.17.26.png

                  The actual content of the icon changes with each program execution BTW.

                  On a related note, I found out that this is indeed a macOS-specific issue, because everything looks fine on Linux and Windows using the same 4K monitor in scaled mode (I'm using the original code snippet from my initial post):

                  hidpi_linux.png
                  hidpi_windows.png

                  I guess this is indeed a Qt bug then and I'll report it. Still, I'd be interested in getting the workaround using QPixmap to actually work - then I could use that on macOS until they've fixed the underlying issue.

                  J Offline
                  J Offline
                  J.Hilk
                  Moderators
                  wrote on 30 Oct 2019, 08:42 last edited by
                  #9

                  @cle1109 have you tried it with a QSvgWidget ? Thats the widget you're supposed to use when drawing/showing svgs.

                  I assume its more sophisticated for the task, than a simple QIcon


                  Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                  Q: What's that?
                  A: It's blue light.
                  Q: What does it do?
                  A: It turns blue.

                  1 Reply Last reply
                  0
                  • C Offline
                    C Offline
                    cle1109
                    wrote on 30 Oct 2019, 11:53 last edited by
                    #10

                    @J-Hilk I'm not sure how I am supposed to set the icon of the action then, because this expects a QIcon.

                    J 1 Reply Last reply 30 Oct 2019, 11:57
                    0
                    • C cle1109
                      30 Oct 2019, 11:53

                      @J-Hilk I'm not sure how I am supposed to set the icon of the action then, because this expects a QIcon.

                      J Offline
                      J Offline
                      J.Hilk
                      Moderators
                      wrote on 30 Oct 2019, 11:57 last edited by
                      #11

                      @cle1109 we would burn that bridge when we get there 😉.
                      I would rather first check if it makes a difference at all.


                      Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                      Q: What's that?
                      A: It's blue light.
                      Q: What does it do?
                      A: It turns blue.

                      1 Reply Last reply
                      0
                      • C Offline
                        C Offline
                        cle1109
                        wrote on 30 Oct 2019, 11:59 last edited by
                        #12

                        It might, and I will test this if I have time, but at the same time I feel that it should just work with a plain and simple QIcon("waves-24px.svg") as on Linux and Windows.

                        J 1 Reply Last reply 30 Oct 2019, 12:01
                        0
                        • C cle1109
                          30 Oct 2019, 11:59

                          It might, and I will test this if I have time, but at the same time I feel that it should just work with a plain and simple QIcon("waves-24px.svg") as on Linux and Windows.

                          J Offline
                          J Offline
                          J.Hilk
                          Moderators
                          wrote on 30 Oct 2019, 12:01 last edited by
                          #13

                          @cle1109 well yes, but sadly the SVG support by Qt is limited. Doesn't work at all on iOS for example, and some common sub formats don't work at all across all platforms :(


                          Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                          Q: What's that?
                          A: It's blue light.
                          Q: What does it do?
                          A: It turns blue.

                          1 Reply Last reply
                          1
                          • C cle1109
                            30 Oct 2019, 08:23

                            Thanks @SimonSchroeder, I've translated the code to Python as follows:

                            import sys
                            from PyQt5.QtWidgets import QApplication, QMainWindow, QAction
                            from PyQt5.QtGui import QIcon, QImage, QPixmap, QPainter
                            
                            
                            app = QApplication(sys.argv)
                            main = QMainWindow()
                            toolbar = main.addToolBar("toolbar")
                            image = QImage("waves-24px.svg")
                            pixmap = QPixmap(toolbar.iconSize())
                            pixmap.setDevicePixelRatio(main.devicePixelRatio())
                            painter = QPainter()
                            painter.begin(pixmap)
                            painter.drawImage(0, 0, image)
                            painter.end()
                            icon = QIcon(pixmap)
                            action = QAction(icon, "Test")
                            toolbar.addAction(action)
                            toolbar.show()
                            main.show()
                            sys.exit(app.exec_())
                            

                            Note that a QMainWindow doesn't have a pixelRatio method so I've replaced that with a call to devicePixelRatio.

                            However, there seems to be something wrong because the result looks like this:

                            Screen Shot 2019-10-30 at 09.17.26.png

                            The actual content of the icon changes with each program execution BTW.

                            On a related note, I found out that this is indeed a macOS-specific issue, because everything looks fine on Linux and Windows using the same 4K monitor in scaled mode (I'm using the original code snippet from my initial post):

                            hidpi_linux.png
                            hidpi_windows.png

                            I guess this is indeed a Qt bug then and I'll report it. Still, I'd be interested in getting the workaround using QPixmap to actually work - then I could use that on macOS until they've fixed the underlying issue.

                            S Offline
                            S Offline
                            SimonSchroeder
                            wrote on 31 Oct 2019, 07:29 last edited by
                            #14

                            @cle1109 That is unfortunate that the workaround does not work on MacOS. I have one more suggestion you could try. Instead of

                            pixmap = QPixmap(toolbar.iconSize())
                            pixmap.setDevicePixelRatio(main.devicePixelRatio())
                            

                            just try

                            pixmap = QPixmap(toolbar.iconSize() * main.devicePixelRatio())
                            

                            There is a slight chance that using pixmap.setDevicePixelRatio does not work properly with SVG on MacOS. In this case this would create a larger icon which is then scaled down when drawing it on the toolbar.

                            1 Reply Last reply
                            0
                            • C Offline
                              C Offline
                              cle1109
                              wrote on 31 Oct 2019, 08:11 last edited by
                              #15

                              @SimonSchroeder I think there is something wrong with the code because like in the first version, I get a more or less random icon with the second version as well. It looks like either the conversion icon = QIcon(pixmap) doesn't work or one of the preceding steps.

                              S 1 Reply Last reply 4 Nov 2019, 07:50
                              0
                              • C cle1109
                                31 Oct 2019, 08:11

                                @SimonSchroeder I think there is something wrong with the code because like in the first version, I get a more or less random icon with the second version as well. It looks like either the conversion icon = QIcon(pixmap) doesn't work or one of the preceding steps.

                                S Offline
                                S Offline
                                SimonSchroeder
                                wrote on 4 Nov 2019, 07:50 last edited by
                                #16

                                @cle1109 You can try if it is one of the preceeding steps by calling pixmap.save(...) and have a look at the saved image.

                                1 Reply Last reply
                                0
                                • C Offline
                                  C Offline
                                  cle1109
                                  wrote on 5 Nov 2019, 08:46 last edited by
                                  #17

                                  I did pixmap.save("pixmap.png") after the painter stuff and the resulting PNG doesn't look right. So either the painter doesn't paint correctly into the pixmap or the image is not read in correctly. Can I debug this further to find out what the problem is?

                                  1 Reply Last reply
                                  0
                                  • S Offline
                                    S Offline
                                    SimonSchroeder
                                    wrote on 6 Nov 2019, 10:36 last edited by
                                    #18

                                    To me, this means that the painter does not paint correctly. I'm out of ideas.

                                    Maybe, one last thing to check: I am not sure how a QPython project would be set up. For C++ I am using qmake. One thing I noticed is that in the end SVG icons are working. However, it would be more correct to add Qt's SVG module, i.e. I would add the line

                                    QT += svg
                                    

                                    to my qmake project file. Is there something similar for Python?

                                    1 Reply Last reply
                                    0
                                    • C Offline
                                      C Offline
                                      cle1109
                                      wrote on 6 Nov 2019, 10:46 last edited by
                                      #19

                                      I don't think this is necessary in Python. It is sufficient to import the required packages. In the example, I don't explicitly require the PyQt5.QtSvg module, but I don't think this is a problem (the stuff I'm using should automatically use functions from that module if needed).

                                      I will rewrite my example in C++ to see if this is a problem specific to the Python bindings. That way, it will be easier to decide where to file the bug report (since this is working on Windows and Linux). I'll keep you posted.

                                      1 Reply Last reply
                                      0
                                      • C Offline
                                        C Offline
                                        cle1109
                                        wrote on 6 Nov 2019, 14:16 last edited by
                                        #20

                                        I tried this example in C++ and the result is exactly the same. The SVG icon is rendered in a very low resolution.

                                        #include <QApplication>
                                        #include <QMainWindow>
                                        #include <QIcon>
                                        #include <QAction>
                                        #include <QToolBar>
                                        
                                        
                                        int main(int argc, char **argv)
                                        {
                                            QApplication app(argc, argv);
                                            QMainWindow window;
                                            QIcon icon("waves-24px.svg");
                                            QAction action(icon, "Test");
                                            QToolBar *toolbar = new QToolBar(&window);
                                            toolbar->addAction(&action);
                                            window.addToolBar(toolbar);
                                            window.show();
                                            return app.exec();
                                        }
                                        
                                        1 Reply Last reply
                                        0
                                        • C Offline
                                          C Offline
                                          cle1109
                                          wrote on 6 Nov 2019, 15:06 last edited by
                                          #21

                                          Also, here's my main.pro file I used to build the app. It doesn't make a difference whether or not I include svg.

                                          TEMPLATE = app
                                          TARGET = main
                                          
                                          QT = core gui widgets
                                          
                                          SOURCES += main.cpp
                                          
                                          1 Reply Last reply
                                          0

                                          11/24

                                          30 Oct 2019, 11:57

                                          • Login

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