Various Issues with PyQt6

RoadrunnerWMC roadrunnerwmc at gmail.com
Sun Feb 7 20:33:25 GMT 2021


Hello. I'm trying to port a PyQt5 application to PyQt6, but am running
into a few issues, which I think are bugs in PyQt6 itself. I've
distilled them down to minimum reproducible examples, all of which
work fine on PyQt5. My environment is Ubuntu 20.04 (KDE Neon), using
the system-provided Python 3.8.5.

Here's an issue with signals/slots signature matching:

    from PyQt6 import QtCore, QtGui, QtWidgets

    class MainWindow(QtWidgets.QMainWindow):
        def __init__(self):
            super().__init__()
            self.myList = QtWidgets.QListWidget()
            self.myList.itemActivated.connect(self.itemActivatedHandler)

        @QtCore.pyqtSlot(QtWidgets.QListWidgetItem)
        def itemActivatedHandler(self, item):
            print('Item activated')

    app = QtWidgets.QApplication([])
    mw = MainWindow()
    mw.show()
    app.exec()

On PyQt 6.0.1, this results in the following traceback:

    Traceback (most recent call last):
      File "/path/to/pyqt6_test.py", line 14, in <module>
        mw = MainWindow()
      File "/path/to/pyqt6_test.py", line 7, in __init__
        self.myList.itemActivated.connect(self.itemActivatedHandler)
    TypeError: decorated slot has no signature compatible with
itemActivated(QListWidgetItem*)

This seems to affect every slot that takes one or more pointers to Qt
objects. If there's a way to denote pointers in the decorator,
something like `@QtCore.pyqtSlot(pointerTo(QtWidgets.QListWidgetItem))`,
it doesn't seem to be explained in the documentation
(https://www.riverbankcomputing.com/static/Docs/PyQt6/signals_slots.html).

Here's a different issue, related to `QtWidgets.QGraphicsItem.itemChange()`:

    from PyQt6 import QtCore, QtGui, QtWidgets

    class CustomGraphicsItem(QtWidgets.QGraphicsItem):
        def boundingRect(self):
            return QtCore.QRectF(0, 0, 10, 10)

        def itemChange(self, change, value):
            return QtWidgets.QGraphicsItem.itemChange(self, change, value)

    class MainWindow(QtWidgets.QMainWindow):
        def __init__(self):
            super().__init__()
            self.scene = QtWidgets.QGraphicsScene(0, 0, 100, 100, self)
            self.view = QtWidgets.QGraphicsView(self.scene, self)

            self.scene.addItem(CustomGraphicsItem())

    app = QtWidgets.QApplication([])
    mw = MainWindow()
    mw.show()
    app.exec()

On PyQt 6.0.1, this results variously in one of the following three
outcomes (most often the second):

    Traceback (most recent call last):
      File "/path/to/pyqt6_test_2.py", line 8, in itemChange
        return QtWidgets.QGraphicsItem.itemChange(self, change, value)
    TypeError: itemChange(self, QGraphicsItem.GraphicsItemChange,
Any): argument 2 has unexpected type 'GraphicsItemChange'

    Traceback (most recent call last):
      File "/usr/lib/python3.8/enum.py", line 309, in __call__
        return cls.__new__(cls, value)
    RecursionError: maximum recursion depth exceeded while calling a
Python object

    Segmentation fault

I notice this example *does* work fine if I replace
`QtWidgets.QGraphicsItem` in `itemChange()`'s body with `super()` or
`super(CustomGraphicsItem, self)`. Maybe that syntax is required now?
But even if so, it shouldn't really be segfaulting if you do it the
wrong way.

Here's a third issue:

    from PyQt6 import QtCore, QtGui, QtWidgets

    class CustomGraphicsView(QtWidgets.QGraphicsView):
        def mouseMoveEvent(self, event):
            print(event.x())

    class MainWindow(QtWidgets.QMainWindow):
        def __init__(self):
            super().__init__()
            self.scene = QtWidgets.QGraphicsScene(0, 0, 100, 100, self)
            self.view = CustomGraphicsView(self.scene, self)
            self.view.setMouseTracking(True)

            self.setCentralWidget(self.view)

    app = QtWidgets.QApplication([])
    mw = MainWindow()
    mw.show()
    app.exec()

On PyQt 6.0.1, running this and then moving your cursor over the
graphics view results in the following traceback:

    Traceback (most recent call last):
      File "/path/to/pyqt6_test_3.py", line 6, in mouseMoveEvent
        print(event.x())
    AttributeError: 'QMouseEvent' object has no attribute 'x'

I don't really have any idea about this one. The same thing happens if
you try to access `.pos()`, so that's not a workaround.


PyQt is by far my favorite GUI framework in any language, so I'm
really looking forward to being able to use PyQt6. Thanks in advance
for any help you can provide!


More information about the PyQt mailing list