Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-105912

QPainter.fillPath draws incorrect with QOpenGLWidget as viewport

    XMLWordPrintable

Details

    • Bug
    • Resolution: Unresolved
    • P2: Important
    • None
    • 5.15.2
    • None
    • Qt 5.15.2, Windows 10, PySide2, Python 3.10
      (Also tested with PyQt5)
    • Windows

    Description

      QPainter.fillPath() results in incorrect pictures when using in QGraphicsItem.paint() with a QOpenGLWidget set as viewport to the corresponding QGraphicsView.

      See the attached screenshot, generated using the mwe below.
      The green filled area painted using QPainter.fillPath(p) differs from the red line painted using QPainter.drawPath(p), where the same p is used for both.

      Note, that if no QOpenGLWidget is used as viewport (remove the two corresponding lines in the mwe), the bug disappears.
      Also the distortion depends on the value ranges of the x values in the mwe. For example, using a small offset x0 = 0 lets the bug also disappear.

      MWE
      The bug can be reproduced with the following mwe, using python 3.10 and PySide2.

      import numpy as np
      from PySide2 import QtCore, QtGui, QtWidgets
      
      class PlotItem(QtWidgets.QGraphicsItem):
      
          def __init__(self, parent, x, y):
              super().__init__(parent)
              self.x = x
              self.y = y
      
          def boundingRect(self):
              return QtCore.QRectF(min(x),min(y), max(x)-min(x), max(y)-min(y))
      
          def paint(self, painter, option, widget):
      
              poly = QtGui.QPolygonF([QtCore.QPointF(x,y) for x,y in zip(self.x,self.y)])
              path = QtGui.QPainterPath()
              path.addPolygon(poly)
      
              # This works correct (only as a reference here)
              pen = QtGui.QPen(QtGui.QColor("#ff0000"))
              pen.setCosmetic(True)
              painter.setPen(pen)
              painter.drawPath(path)
      
              # This doesn't work
              painter.fillPath(path, QtGui.QBrush(QtGui.QColor("#00ff00")))
      
      
      x0 = 100000.0  # Large error
      # x0 = 20000  # Small error
      # x0 = 0  # Works
      
      x_range = 0.1
      num_samples = 10
      
      x = np.linspace(x0, x0+x_range, num_samples, endpoint=False)
      y = -np.linspace(0,1,num_samples, endpoint=False)
      x = x[:len(y)]
      y[::2] = 0.0
      y = np.concatenate(([0.0], y, [0.0]))
      x = np.concatenate(([x[0]], x, [x[-1]]))
      # [print([x_,y_]) for x_,y_ in zip(x,y)]
      
      
      app = QtWidgets.QApplication()
      scene = QtWidgets.QGraphicsScene()
      view = QtWidgets.QGraphicsView(scene)
      view.resize(300,200)
      
      v = QtWidgets.QOpenGLWidget()
      view.setViewport(v)
      
      view.show()
      
      scene.setBackgroundBrush(QtGui.QBrush(QtGui.QColor("black")))
      
      plot_item = PlotItem(None,x,y)
      scene.addItem(plot_item)
      
      view.fitInView(plot_item)
      
      app.exec_()
      

      Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            qt.team.graphics.and.multimedia Qt Graphics Team
            bbc131 Björn Bissinger
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:

              Gerrit Reviews

                There are no open Gerrit changes