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
QtWS25 Last Chance

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.
  • C cle1109

    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.HilkJ Offline
    J.HilkJ Offline
    J.Hilk
    Moderators
    wrote on 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 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.HilkJ 1 Reply Last reply
      0
      • C cle1109

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

        J.HilkJ Offline
        J.HilkJ Offline
        J.Hilk
        Moderators
        wrote on 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 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.HilkJ 1 Reply Last reply
          0
          • C cle1109

            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.HilkJ Offline
            J.HilkJ Offline
            J.Hilk
            Moderators
            wrote on 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

              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 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 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
                0
                • C cle1109

                  @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 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 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 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 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 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 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
                            • S Offline
                              S Offline
                              SimonSchroeder
                              wrote on last edited by
                              #22

                              You'll need to use the trick with the QPixmap and QPainter in C++ as well. In the background Python and C++ use the exact same functionality, so I wouldn't expect any other behavior without the workaround. (I have experienced this exact problem in C++ multiple times.)

                              For your main.pro you need to add the svg module also:

                              ...
                              QT = core gui widgets svg
                              ...
                              

                              This is what I actually meant with my last post.

                              1 Reply Last reply
                              0
                              • C Offline
                                C Offline
                                cle1109
                                wrote on last edited by
                                #23

                                You'll need to use the trick with the QPixmap and QPainter in C++ as well. In the background Python and C++ use the exact same functionality, so I wouldn't expect any other behavior without the workaround. (I have experienced this exact problem in C++ multiple times.)

                                I get exactly the same result as in Python (the icon is just a random pixel pattern).

                                Yes, I know what you meant, I tried adding svg but it didn't make any difference. Same for the workaround. So in conclusion, this seems to be a Qt bug on macOS which also affects PyQt5.

                                1 Reply Last reply
                                0
                                • C Offline
                                  C Offline
                                  cle1109
                                  wrote on last edited by
                                  #24

                                  Turns out there is a simple solution:

                                  app.setAttribute(Qt.AA_UseHighDpiPixmaps)
                                  
                                  1 Reply Last reply
                                  6

                                  • Login

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