-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
try getting PyPySide to work #2271
base: master
Are you sure you want to change the base?
Conversation
So the reason for #2132 is also the reason why CPython bindings were crashing once the inheritance order was swapped. |
The ROI Issue seems limited to the EDIT: another potential clue, in the ROI example, the handle scales with the zoom of the viewbox, which should not happen, it should remain the same size regardless of zoom level. |
As far as I can tell, both import pyqtgraph as pg
pg.mkQApp()
pw = pg.PlotWidget()
pw.show()
r2a = pg.PolyLineROI([[0,0], [10,10], [10,30], [30,10]], closed=True)
pw.addItem(r2a)
r2b = pg.PolyLineROI([[0,-20], [10,-10], [10,-30]], closed=False)
pw.addItem(r2b)
r2c = pg.LineSegmentROI([[15, -15], [30, -15]])
pw.addItem(r2c)
pw.disableAutoRange('xy')
pw.autoRange()
pg.exec() |
By adding a judicious CPython PySide 6.3.0 (py38_pyside6) PS C:\work\repos\pyqtgraph> python C:\work\pyqtgraph\simple_roi.py
<PySide6.QtWidgets.QGraphicsRectItem(0x21742530780, parent=0x21742892a00, pos=0,0, z=1000) at 0x0000021743462880> False
<pyqtgraph.graphicsItems.PlotItem.PlotItem.PlotItem(0x217428919f0, pos=0,0, flags=(ItemUsesExtendedStyleOption|ItemSendsGeometryChanges)) at 0x000002174345EC80> False
<pyqtgraph.graphicsItems.ROI.Handle(0x21742aa7160, parent=0x21742a91c50, pos=15,-15, z=11, flags=(ItemSendsGeometryChanges|ItemSendsScenePositionChanges)) at 0x00000217460E7E80> True
<ViewBox(0x217428929f0, parent=0x21742891a00, pos=23.7344,1, z=-100, flags=(ItemIsFocusable|ItemClipsChildrenToShape|ItemUsesExtendedStyleOption|ItemSendsGeometryChanges)) at 0x000002174345EFC0> True PyPy PySide6 6.3.0 (pypy) C:\work\repos\pyqtgraph>python \work\pyqtgraph\simple_roi.py
<PySide6.QtWidgets.QGraphicsRectItem(0x2c4d8ab3cd0, parent=0x2c4d7517f90, pos=0,0, z=1000) at 0x000002C4D8AB3C90> False
<pyqtgraph.graphicsItems.PlotItem.PlotItem.PlotItem(0x2c4d7473790, pos=0,0, flags=(ItemUsesExtendedStyleOption|ItemSendsGeometryChanges)) at 0x000002C4D8AB3010> False
<PySide6.QtWidgets.QGraphicsItem(0x2c4d7c6a260, parent=0x2c4d7c65ac0, pos=15,-15, z=11, flags=(ItemSendsGeometryChanges|ItemSendsScenePositionChanges)) at 0x000002C4D8CF8F20> False
<ViewBox(0x2c4d7517f80, parent=0x2c4d74737a0, pos=23.7344,1, z=-100, flags=(ItemIsFocusable|ItemClipsChildrenToShape|ItemUsesExtendedStyleOption|ItemSendsGeometryChanges)) at 0x000002C4D8AB3110> True |
I guess that would explain it; probably need to sprinkle in some |
Just retrieving the from PySide6 import QtWidgets
import pyqtgraph as pg
app = QtWidgets.QApplication([])
scene = QtWidgets.QGraphicsScene(0, 0, 400, 400)
view = QtWidgets.QGraphicsView(scene)
roi = pg.LineSegmentROI([[15, -15], [30, -15]])
scene.addItem(roi)
items = view.scene().items()
for item in items:
print(item) |
Most confusion ...with a slight modification of your example: from PySide6 import QtWidgets
import contextlib
import pyqtgraph as pg
app = QtWidgets.QApplication([])
scene = QtWidgets.QGraphicsScene(0, 0, 400, 400)
view = QtWidgets.QGraphicsView(scene)
roi = pg.LineSegmentROI([[15, -15], [30, -15]])
scene.addItem(roi)
items = view.scene().items()
for item in items:
print(f"{type(item)=}")
print([type(handle['item']) for handle in roi.handles])
print([(handle['item'].scene() is view.scene()) for handle in roi.handles]) This indicates the handles are still of type |
If we do a type(item)=<class 'PySide6.QtWidgets.QGraphicsItem'>
C++ address....... PySide6.QtWidgets.QGraphicsItem/0000016EAA88D530
hasOwnership...... 0
containsCppWrapper 0
validCppObject.... 1
wasCreatedByPython 0 where on CPython, |
c31e17d
to
15b583e
Compare
I am only just "discovering" that PyQt but not PySide does the equivalent of a To avoid from pyqtgraph.Qt import QtCore
class M:
def __init__(self):
print("M.__init__")
class C1(M, QtCore.QObject):
def __init__(self):
M.__init__(self)
QtCore.QObject.__init__(self)
class C2(QtCore.QObject, M):
def __init__(self):
QtCore.QObject.__init__(self)
M.__init__(self)
print('C1')
c1 = C1()
print('C2')
c2 = C2() |
Huh, I had no idea about this. I wonder if this explains some past weird behavior.
I'm wondering if this should be explicitly stated somewhere, like a comment in the |
The current code in master has I think maybe for |
There's something wrong on PyPySide6 when running the Traceback (most recent call last):
File "c:\work\repos\pyqtgraph\pyqtgraph\widgets\GraphicsView.py", line 137, in paintEvent
return super().paintEvent(ev)
TypeError: 'PySide6.QtWidgets.QGraphicsView.paintEvent' called with wrong argument types:
PySide6.QtWidgets.QGraphicsView.paintEvent(QPainter)
Supported signatures:
PySide6.QtWidgets.QGraphicsView.paintEvent(PySide6.QtGui.QPaintEvent) UPDATE: this error seems to have gone away with PyPySide 6.3.1 |
The The big issue is the crashing when the QWidget is not listed as the left-most class in multiple inheritance. This breaks the recommended code pattern of placing Mix-In classes on the left-hand-side. |
I got it in my head that that may have been patched in 6.3.1; probably should file a bug-report for that too; I alerted the pyside maintainer that has been working on this on the gitter chat, but it may have been lost in the noise. |
d57384b
to
2bfb519
Compare
A minimal Parameter Tree test-case that passes on CPython but fails on PyPy. The issue can be described as follows: The baffling thing is that all objects are converted to str type when it gets set to the Parameter anyway, so it shouldn't have mattered at all what the original object was. Of course, it probably doesn't make practical sense to be setting a brush or a pen to a "str" Parameter to begin with. import pyqtgraph as pg
import pyqtgraph.parametertree as pt
app = pg.mkQApp()
def check(param):
objs = [pg.mkColor('k'), pg.mkBrush('k'), pg.mkPen('k')]
results = []
for obj in objs:
param.setValue(obj)
results.append(str(obj) == param.value())
return results
def test_param():
param = pt.Parameter.create(name='params', type='str')
results = check(param)
assert all(results), results
def test_tree():
root = pt.Parameter.create(name='params', type='group', children=[
dict(name='str', type='str')
])
tree = pt.ParameterTree()
tree.setParameters(root)
param = root.child('str')
results = check(param)
assert all(results), results |
d691411
to
9b43579
Compare
I have a more minimal test-case to demonstrate the ROI-Handle decay issue in |
9f00d09
to
0067bfe
Compare
Triggered a CI-run with PyPySide 6.3.2. No change in failing test cases. |
I profiled this branch with 1000 iterations of PlotSpeedTest.py to try and better see where the discrepancy in performance is. Results are a bit puzzling, the call tree in CPython looks like what I would expect, but in PyPy it's a decent amount different. Also I'm not seeing entries for methods in the PyPy table that correspond to EDIT: tried running the pypy version w/ vmprof, but that resulted in a segfault so .... EDIT2: In PyPy, looks like boundingRect is one of the sources of a major penalty as is PlotCurveItem.updateData CPythonTop 10 entries sorted by "own time" PyPyTop 10 entries sorted by "own time" |
Triggered a CI run with PyPySide 6.4.0 using the PyPy 3.9 wheels available on pypi.org. No change in failing test cases. |
The pypi.org provided wheels of PyPySide6 (6.4.1, 6.4.2) segfault immediately upon from PySide6 import QtCore when used with the latest versions of PyPy 3.9 (7.3.10, 7.3.11).
Closing this PR as there's nothing that |
A fix for the crash has been merged (https://bugreports.qt.io/browse/PYSIDE-2264) but will only arrive in PySide6 6.5 |
there are 2 methods of Container that are meant to take precedence over QWidget. - childEvent() - this was renamed to childEvent_() in 6dbda78 to workaround a bug in early versions of PyQt6. - close() - this is renamed to close_() in this commit
ROI handles currently don't work
- mixin lhs inheritance crashes on PyPy - after changing the mixin to rhs, we have the following issues: - GLViewMixin.__init__ calls a QOpenGLWidget method. This fails on PyPySide 6.5.0's implementation of cooperative inheritance. It complains that QOpenGLWidget has not been initialized yet. - GLViewMixin overrides some of QOpenGLWidget's methods, and this doesn't work if the mixin is on the rhs
With regards to #2270, experiment with swapping inheritance order to get GraphicsItem(s) to work on PyPy.
Except for PySide6 (tested on 6.2.4 and 6.3.0), the patches here cause all other CPython bindings to fail or crash.Note: The combination of Python 3.10 + PySide6 6.3.0 already fails for other reasons.
The various GraphicItem(s) seem to work.
Dragging of ROI Handles don't work.
The existing codebase does assume the method resolution order of inheriting
GraphicsItem
beforeQGraphicsWidget
/QGraphicsObject
.