Details
-
Bug
-
Resolution: Incomplete
-
P2: Important
-
None
-
5.11.2
-
None
Description
The PySide2 document that best explains creating Qt Properties seems to be this one:
https://wiki.qt.io/Qt_for_Python_UsingQtProperties
This makes no mention of the @Property decorator, which does exist, and which has an analog in PyQt5, according to https://stackoverflow.com/questions/52046551/using-radialbar-qml-port-with-pyqt5. Note the use of setters in PyQt5 – maybe there is a similar way to define a setter in PySide2 but I was unable to find it.
Here's PyQt5 example code, along with QML.
import sys from PyQt5.QtCore import pyqtSlot, pyqtProperty, pyqtSignal, QObject, QUrl from PyQt5.QtWidgets import QApplication from PyQt5.QtQml import QQmlApplicationEngine from PyQt5.QtQml import qmlRegisterType class DataContainer(QObject): dataChanged = pyqtSignal() def __init__(self, parent=None): super().__init__(parent) self._data = "" @pyqtProperty(str, notify=dataChanged) def data(self): return self._data @data.setter def data(self, value): print("Set " + value) self._data = value self.dataChanged.emit() if __name__ == "__main__": app = QApplication(sys.argv) qmlRegisterType(DataContainer, "MyStuff", 1, 0, "DataContainer") engine = QQmlApplicationEngine() engine.load(QUrl("main.qml")) sys.exit(app.exec_())
import QtQuick 2.9 import QtQuick.Controls 1.4 import MyStuff 1.0 ApplicationWindow { visible: true width: 1280 height: 1024 title: "Bug Report" DataContainer { data: "blahblah" } }
Note the setter prints as expected. Now try replacing PyQt5 with PySide2 as follows:
import sys from PySide2.QtCore import Slot, Property, Signal, QObject, QUrl from PySide2.QtWidgets import QApplication from PySide2.QtQml import QQmlApplicationEngine from PySide2.QtQml import qmlRegisterType class DataContainer(QObject): dataChanged = Signal() def __init__(self, parent=None): super().__init__(parent) self._data = "" @Property(str, notify=dataChanged) def data(self): return self._data @data.setter def data(self, value): print("Set " + value) self._data = value self.dataChanged.emit() if __name__ == "__main__": app = QApplication(sys.argv) qmlRegisterType(DataContainer, "MyStuff", 1, 0, "DataContainer") engine = QQmlApplicationEngine() engine.load(QUrl("main.qml")) sys.exit(app.exec_())
This fails to load the QML, you will see error text:
Cannot assign to non-existent property "data"