Details
Description
Running the attached "testslots.py" results in the following output:
6.3.2 OBJECT A::unnamed SIGNALS OUT signal: sig() --> A::unnamed slotA() SIGNALS IN <-- A::unnamed slotA() OBJECT B::unnamed SIGNALS OUT signal: destroyed(QObject*) --> __GlobalReceiver__::unnamed __receiverDestroyed__(QObject*) signal: sig() --> __GlobalReceiver__::unnamed slotA2a0eb197bc02a0e8fc64d0() SIGNALS IN <None>
When A (the base class) is used by itself, the slots connect properly. However, when B (the subclass) is used, despite nothing being overridden, the slots all connect using the global receiver.
The root cause of this appears to be the getReceiver (https://code.qt.io/cgit/pyside/pyside-setup.git/tree/sources/pyside6/libpyside/qobjectconnect.cpp?h=6.5#n111) function. On line 111, there is a check which is meant to check if the slot is a C++ slot overridden in Python. But since the meta object in use is the meta object of the subclasses, the check treats superclass Python slots like C++ slots, and decides that they override themselves. (for the attached code, methodOffset() returns 7, slotIndex is 6 and PyMethod_Check(callback) returns true)
The reason I noticed this was a due to a "Internal C++ object (...) already deleted" error in our codebase. I've attached a file (crash.py) that can reproduce this error, which seems to some how create the perfect timing to get this error. It only causes the error on Windows, and does seem rather contrived, but it is a simplified version of what we had in our codebase and if we hit it by accident there must be other cases as well. To reproduce:
- Start the script
- Move the window to another monitor (in my case my monitors have different DPIs, not sure if that matters)
- Click open
- Then close the window that opens
The output for me is:
PySide6.QtCore.QSizeF(160.000000, 160.000000)
Traceback (most recent call last):
File "C:\Users\matthew.joyce\Repos\iscat_gui\crash.py", line 23, in _onSceneChange
print(self.size())
RuntimeError: Internal C++ object (CalibrationGraph) already deleted.
Bye
The slot inconsistency happens on both Linux and Windows, with multiple PySide versions.
Attachments
Issue Links
- resulted in
-
PYSIDE-2487 Reg->6.5.3: Cannot Disconnect Signal That is Inherited to slot that has no Slot() decorator
- Closed
For Gerrit Dashboard: PYSIDE-2418 | ||||||
---|---|---|---|---|---|---|
# | Subject | Branch | Project | Status | CR | V |
497960,6 | Fix connections to base class slots falling back to global receiver | dev | pyside/pyside-setup | Status: MERGED | +2 | 0 |
498035,2 | Brush up code related to pre-Jira bug 1019 | dev | pyside/pyside-setup | Status: MERGED | +2 | 0 |
498228,2 | Brush up code related to pre-Jira bug 1019 | 6.5 | pyside/pyside-setup | Status: MERGED | +2 | 0 |
498229,2 | Fix connections to base class slots falling back to global receiver | 6.5 | pyside/pyside-setup | Status: MERGED | +2 | 0 |
511601,3 | Fix disconnecting non-decorated slot of base class from signal | dev | pyside/pyside-setup | Status: MERGED | +2 | 0 |
511720,2 | Fix disconnecting non-decorated slot of base class from signal | 6.6 | pyside/pyside-setup | Status: MERGED | +2 | 0 |
511770,2 | Fix disconnecting non-decorated slot of base class from signal | 6.5 | pyside/pyside-setup | Status: MERGED | +2 | 0 |