Details
-
Bug
-
Resolution: Unresolved
-
P3: Somewhat important
-
None
-
5.15.0
-
None
Description
Years ago, Qt bug 29836 meant that if a class were derived from QQmlPropertyMap, then its slots were not callable. This was fixed, but it's still reproducible if the class uses the default QQmlPropertyMap constructor. The solution/workaround is to use its protected, two-argument constructor instead, as noted in the documentation:
When deriving a class from QQmlPropertyMap, use the protected two-argument constructor which ensures that the class is correctly registered with the Qt Meta-Object System.
As far as I'm aware, there's no way to choose a different constructor when inheriting from QQmlPropertyMap in PySide2. This means it's impossible to inherit from the class in Python and be able to use any slots defined in the new class.
Attached is a simple test with both a C++ and a Python file, both using the same QML. The C++ file demonstrates that a slot works after the protected constructor, but not after the default one; the Python file demonstrates that a slot works for a QObject, but not for an otherwise identical QQmlPropertyMap. Clicking in the window will attempt to call both slots.
Example of output (from the Python file):
QQmlExpression: Expression file:///home/.../pyside1341/main.qml:10:10 depends on non-NOTIFYable properties:
MyObj::field
QObject signal worked
TypeError: Property 'test_func' of object QQmlPropertyMap(0x7fadf474b240) is not a function
EDIT: Using the wrong constructor also means that qproperties defined in the inheriting class (rather than being inserted as a key/value into the map) aren't exposed to QML either. I've amended the test code so that it demonstrates this as well.
Attachments
Issue Links
- relates to
-
QTBUG-29836 Cannot call slot or Q_INVOKABLE from QML in QQmlPropertyMap subclass
- Closed