Repository: pyqtgraph/pyqtgraph

Issue:
examples/ScatterPlot.py : different output for PyQt6
<!-- In the following, please describe your issue in detail! -->
<!-- If some of the sections do not apply, just remove them. -->

### Short description
<!-- This should summarize the issue. -->
When running examples/ScatterPlot.py, PyQt6 binding creates an output that looks different from the other bindings.

### Code to reproduce
<!-- Please provide a minimal working example that reproduces the issue in the code block below.
     Ideally, this should be a full example someone else could run without additional setup. -->
```examples/ScatterPlot.py```

### Expected behavior
<!-- What should happen? -->
Ouput from all bindings should look similar.
Output from PyQt5, PySide2, PySide6
![scatter_pyqt5](https://user-images.githubusercontent.com/2657027/121762861-2d7c6b80-cb6b-11eb-8cda-966b89af798d.png)

### Real behavior
<!-- What happens? -->
Output from PyQt6 looks different than other bindings
![scatter_pyqt6](https://user-images.githubusercontent.com/2657027/121762867-3c631e00-cb6b-11eb-80cb-290fe9f01637.png)

### Tested environment(s)

 * PyQtGraph version: master 2021/06/12 <!-- output of pyqtgraph.__version__ -->
 * Qt Python binding: PyQt5 5.15, PySide2 5.15, PySide6 6.1.1, PyQt6 6.1.0 <!-- output of pyqtgraph.Qt.VERSION_INFO -->
 * Python version: 3.8.10
 * NumPy version: 1.20.3 <!-- output of numpy.__version__ -->
 * Operating system: Windows 10 20H2
 * Installation method: pip install -e . 
<!-- e.g. pip, conda, system packages, ... -->

### Additional context

This seems to be a regression with PyQt6 6.1 with respect to PyQt6 6.0.
Checking out a commit of pyqtgraph that works with both PyQt6 6.0 and PyQt6 6.1 shows that 6.0 gives the expected output while 6.1 gives the differing output.


Discussion:
Any chance this is a consequence of an email namespace getting missed?

On Fri, Jun 11, 2021 at 19:58 pijyoi ***@***.***> wrote:

> Short description
>
> When running examples/ScatterPlot.py, PyQt6 binding creates an output that
> looks different from the other bindings.
> Code to reproduce
>
> examples/ScatterPlot.py
> Expected behavior
>
> Ouput from all bindings should look similar.
> Output from PyQt5, PySide2, PySide6
> [image: scatter_pyqt5]
> <https://user-images.githubusercontent.com/2657027/121762861-2d7c6b80-cb6b-11eb-8cda-966b89af798d.png>
> Real behavior
>
> Output from PyQt6 looks different than other bindings
> [image: scatter_pyqt6]
> <https://user-images.githubusercontent.com/2657027/121762867-3c631e00-cb6b-11eb-80cb-290fe9f01637.png>
> Tested environment(s)
>
>    - PyQtGraph version: master 2021/06/12
>    - Qt Python binding: PyQt5 5.15, PySide2 5.15, PySide6 6.1.1, PyQt6
>    6.1.0
>    - Python version: 3.8.10
>    - NumPy version: 1.20.3
>    - Operating system: Windows 10 20H2
>    - Installation method: pip install -e .
>
> Additional context
>
> This seems to be a regression with PyQt6 6.1 with respect to PyQt6 6.0.
> Checking out a commit of pyqtgraph that works with both PyQt6 6.0 and
> PyQt6 6.1 shows that 6.0 gives the expected output while 6.1 gives the
> differing output.
>
> —
> You are receiving this because you are subscribed to this thread.
> Reply to this email directly, view it on GitHub
> <https://github.com/pyqtgraph/pyqtgraph/issues/1832>, or unsubscribe
> <https://github.com/notifications/unsubscribe-auth/AAE5Z7V5CHAZXITXSBPYGEDTSLEMRANCNFSM46R2PPHA>
> .
>

>Any chance this is a consequence of an email namespace getting missed?

If I checkout the merge of #1771 eed220e874af591f520372f22202d1ecb3d112ac, which was just after PyQt6 6.1.0 was released, we find that PyQt6 6.0.3 has the expected output but PyQt6 6.1.0 has the differing output.

So it does not have to do with changing the enums to the long spelling.
Thanks for checking that out; I'm not that familiar w/ the scatter plot.

I'm not too familiar with navigation on the riverbank computing site; but this bit caught my attention from the changelog: https://www.riverbankcomputing.com/static/Downloads/PyQt6/ChangeLog


```
	* NEWS, PyQt6.msp, qpy/QtCore/qpycore_qlist.sip:
	Updated QColorSpec for Qt v6.1.
	[102dcde6cb12]
```

I'm not sure if there is a way to see more details about that change.
I can see the same issue on macOS; really looks like the alpha isn't being handled properly... I'll try and investigate a bit more.
Been working on a non-pyqtgraph dependent MWE for this to report upstream; and I can't seem to trigger the issue.

I'm calling it a night, and weekends are generally pretty busy for me; so I'll post what I have right now in case anyone else wants to give this a go:

```python
import sys

from PyQt6.QtWidgets import QGraphicsObject, QGraphicsView, QApplication, QGraphicsScene, QGraphicsRectItem
from PyQt6.QtGui import QPainter, QBrush, QColor, QPicture, QPixmap
from PyQt6.QtCore import QRectF, Qt


class Example(QGraphicsObject):

    def __init__(self, parent=None):
        super().__init__(parent)
        # self.scene = QGraphicsScene()
        # self.setScene(self.scene)
        self.picture = QPicture()

        self.setup_scene()


    def setup_scene(self):
        # self.scene.setSceneRect(-10, -10, 10, 10)

        alpha = 40
        red = QColor(Qt.GlobalColor.red)
        red.setAlpha(alpha)
        redBrush = QBrush(red)
        blue = QColor(Qt.GlobalColor.blue)
        blue.setAlpha(alpha)
        blueBrush = QBrush(blue)

        # redRect = QGraphicsRectItem(-20, -20, 40, 40)
        # redRect.setBrush(redBrush)

        # blueRect = QGraphicsRectItem(0, 0, 40, 40)
        # blueRect.setBrush(blueBrush)

        # self.scene.addItem(blueRect)
        # self.scene.addItem(redRect)

        redRect = QRectF(-20, -20, 40, 40)
        blueRect = QRectF(0, 0, 40, 40)

        redPixmap = QPixmap(40, 40)
        redPixmap.fill(red)
        bluePixmap = QPixmap(40, 40)
        bluePixmap.fill(blue)

        p = QPainter(self.picture)
        # p.setBrush(redBrush)
        # p.drawRect(redRect)
        p.drawPixmap(-10, -10, redPixmap)
        # p.setBrush(blueBrush)
        p.drawPixmap(0, 0, bluePixmap)
        p.end()

    def paint(self, painter, option, widget=None):
        painter.drawPicture(0, 0, self.picture)

    def boundingRect(self):
        ## boundingRect _must_ indicate the entire area that will be drawn on
        ## or else we will get artifacts and possibly crashing.
        ## (in this case, QPicture does all the work of computing the bouning rect for us)
        return QRectF(self.picture.boundingRect())


if __name__ == "__main__":
    app = QApplication(sys.argv)
    example = Example()
    window = QGraphicsView()
    window.setScene(QGraphicsScene(parent=window))
    window.scene().addItem(example)
    window.resize(640, 480)
    window.show()

    sys.exit(app.exec())
```


Resolving patch:
diff --git a/pyqtgraph/graphicsItems/ROI.py b/pyqtgraph/graphicsItems/ROI.py
--- a/pyqtgraph/graphicsItems/ROI.py
+++ b/pyqtgraph/graphicsItems/ROI.py
@@ -23,6 +23,7 @@
 from .UIGraphicsItem import UIGraphicsItem
 from .. import getConfigOption
 import warnings
+import sys
 
 translate = QtCore.QCoreApplication.translate
 
@@ -1287,7 +1288,7 @@ def renderShapeMask(self, width, height):
             return np.empty((width, height), dtype=float)
         
         im = QtGui.QImage(width, height, QtGui.QImage.Format.Format_ARGB32)
-        im.fill(0x0)
+        im.fill(QtCore.Qt.GlobalColor.transparent)
         p = QtGui.QPainter(im)
         p.setPen(fn.mkPen(None))
         p.setBrush(fn.mkBrush('w'))
@@ -1297,8 +1298,9 @@ def renderShapeMask(self, width, height):
         p.translate(-bounds.topLeft())
         p.drawPath(shape)
         p.end()
-        mask = fn.imageToArray(im, transpose=True)[:,:,0].astype(float) / 255.
-        return mask
+        cidx = 0 if sys.byteorder == 'little' else 3
+        mask = fn.qimage_to_ndarray(im)[...,cidx].T
+        return mask.astype(float) / 255
         
     def getGlobalTransform(self, relativeTo=None):
         """Return global transformation (rotation angle+translation) required to move 
diff --git a/pyqtgraph/graphicsItems/ScatterPlotItem.py b/pyqtgraph/graphicsItems/ScatterPlotItem.py
--- a/pyqtgraph/graphicsItems/ScatterPlotItem.py
+++ b/pyqtgraph/graphicsItems/ScatterPlotItem.py
@@ -120,7 +120,7 @@ def renderSymbol(symbol, size, pen, brush, device=None):
     penPxWidth = max(math.ceil(pen.widthF()), 1)
     if device is None:
         device = QtGui.QImage(int(size+penPxWidth), int(size+penPxWidth), QtGui.QImage.Format.Format_ARGB32)
-        device.fill(0)
+        device.fill(QtCore.Qt.GlobalColor.transparent)
     p = QtGui.QPainter(device)
     try:
         p.setRenderHint(p.RenderHint.Antialiasing)


Test patch: