Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt for Python
  4. Insane / Madness millimeters to scene units (pixels) transformations when loading an SVG image via QGraphicsSVGItem
Forum Updated to NodeBB v4.3 + New Features

Insane / Madness millimeters to scene units (pixels) transformations when loading an SVG image via QGraphicsSVGItem

Scheduled Pinned Locked Moved Unsolved Qt for Python
5 Posts 1 Posters 644 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.
  • QtFCQ Offline
    QtFCQ Offline
    QtFC
    wrote on last edited by QtFC
    #1

    I use Qt Version: 5.15.4

    And i have an A3 sheet ( 420mm x 297mm ) in SVG format. Just a frame. When I load it to QGraphicsView->QGraphicsScene,

    from PySide import QtGui, QtCore, QtSvg
    
    scene = QtGui.QGraphicsScene()
    renderer = QtSvg.QSvgRenderer()
    data = '''<?xml version="1.0" encoding="UTF-8"?>
    <svg width="420mm" height="297mm" version="1.1" viewBox="0 0 420 297" xmlns="http://www.w3.org/2000/svg">
     <rect width="420" height="297" fill="#ffffff" stop-color="#000000" stroke="#f22b2b" stroke-width=".1"/>
    </svg>'''
    renderer.load(data.encode())
    svg = QtSvg.QGraphicsSvgItem()
    svg.setSharedRenderer(renderer)
    scene.addItem(svg)                
    svg.setPos(0,0)
    # This affects the picture but not the numbers in viewBoxF or boundingRect
    svg.renderer().setAspectRatioMode(QtCore.Qt.KeepAspectRatio)
    
    print(str(svg.renderer().viewBoxF()))
    print(str(svg.boundingRect()))
    

    I get the following data:

    svg.renderer().viewBoxF()
    PySide2.QtCore.QRectF(0.000000, 0.000000, 420.000000, 297.000000)
    svg.boundingRect()
    PySide2.QtCore.QRectF(0.000000, 0.000000, 1488.000000, 1052.000000)
    

    I'm trying to determine how many pixels occupies one millimeter in Qt. Let's try together?

    1488/420 = 3.5428
    1052/297 = 3.5420
    

    What???

    How Qt does it happen that a millimeter horizontally differs from a millimeter diagonally? How does Qt manage to convert the image so crookedly...

    And yes, the sheet is depicted really crooked, but this can only be seen at high magnification ...

    This can be fixed by applying:
    setAspectRatioMode(QtCore.Qt.KeepAspectRatio)
    But it doesn't affect the numbers.

    Ok i add other SVG picture. Simple rect ( 30mm x 10mm ). And i get:

    svg.renderer().viewBoxF()
    PySide2.QtCore.QRectF(0.000000, 0.000000, 106.000000, 35.000000) 
    svg.boundingRect()
    PySide2.QtCore.QRectF(0.000000, 0.000000, 30.000000, 10.000000)
    

    Calcualte aspect ratio...

    106/30 = 3.5333
    30/10 = 3
    

    Wow! It's amazing! And here are completely different numbers.
    This is what happens each picture has its own individual AspectRatio???
    Moreover, each side has its own unique ...

    And now try to make some kind of QGraphicsScene in which it is implemented Snap to Grid feature...
    And you end up with something crooked and ugly. Because from the calculations it’s not even clear how many pixels exactly should fit in one millimeter ...

    And the reason seems to me that when the SVG is converted, its size is rounded to the nearest integer. Notice the numbers: 1488.000000, 1052.000000

    Where does such accuracy come from? Why not 1488.5262, 1052.6543 for example?

    What to do with it? How to get accurate graphics in millimeters, not a deformed...

    Maybe that's fixed in Qt6?

    Thanks!

    1 Reply Last reply
    0
    • QtFCQ Offline
      QtFCQ Offline
      QtFC
      wrote on last edited by
      #2

      Source code of SVG files:

      <?xml version="1.0" encoding="UTF-8"?>
      <svg width="420mm" height="297mm" version="1.1" viewBox="0 0 420 297" xmlns="http://www.w3.org/2000/svg">
       <rect width="420" height="297" fill="#ffffff" stop-color="#000000" stroke="#f22b2b" stroke-width=".1"/>
      </svg>
      
      <?xml version="1.0" encoding="UTF-8"?>
      <svg width="30mm" height="10mm" version="1.1" viewBox="0 0 30 10" xmlns="http://www.w3.org/2000/svg">
       <rect width="30" height="10" fill="#ffffff" stop-color="#000000" stroke="#00ffbb" stroke-width=".1"/>
      </svg>
      
      1 Reply Last reply
      0
      • QtFCQ Offline
        QtFCQ Offline
        QtFC
        wrote on last edited by QtFC
        #3

        I think something in the Qt code rounds the sizes and this is basically logical if there are numbers like 200.0000000000001 , but then need to round numbers not to an integer, but, for example, to five decimal places.

        So that numbers like 123.432537675768
        are converted to 123.43254 and not 123.00000.

        1 Reply Last reply
        0
        • QtFCQ Offline
          QtFCQ Offline
          QtFC
          wrote on last edited by
          #4

          Could this be a bug in PySide?

          1 Reply Last reply
          0
          • QtFCQ Offline
            QtFCQ Offline
            QtFC
            wrote on last edited by QtFC
            #5

            Really nobody faced it?

            https://bugreports.qt.io/browse/PYSIDE-2167

            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