I am working with PySide2 and QML. When I define a QtCore.Property
in a Python object, it successfully sets up access for QML as well as the Python property get/set methods. However, I have a situation where it would be useful to attach the Property after defining the class, and this isn't working as I would expect.
First, an example that DOES work:
import sys
from PySide2.QtCore import QObject, Property, Signal
from PySide2.QtGui import QGuiApplication
from PySide2.QtQml import QQmlApplicationEngine
class Person(QObject):
def get_name(self):
print('trying to access name')
return self._name
def set_name(self, new_name):
print('trying to set name')
self._name = new_name
name = Property(str, get_name, set_name)
bob = Person()
bob.name = 'Bob'
print(f'Name: "{bob.name}"')
print(bob.__dict__)
app = QGuiApplication(sys.argv)
engine = QQmlApplicationEngine()
engine.rootContext().setContextProperty('backend', bob)
engine.load("example.qml")
sys.exit(app.exec_())
And a simple QML file to view:
import QtQuick 2.15
import QtQuick.Window 2.15
Window {
visible: true
Component.onCompleted: { console.debug(JSON.stringify(backend)) }
Text { text: backend.name }
}
The resulting graphical window displays "Bob", and the console output includes:
trying to set name
trying to access name
Name: "Bob"
{'_name': 'Bob'}
qml: {"objectName":"","name":"Bob"}
However, with what seems like a simple change, things get confusing. I replaced the Python class definition with:
class Person(QObject):
pass
def get_name(obj):
print('trying to access name')
return obj._name
def set_name(obj, new_name):
print('trying to set name')
obj._name = new_name
Person.name = Property(str, get_name, set_name)
That is, the getter, setter, and Property are defined outside of the class definition, and attached to it after the fact. What's strange is that QML can't see the Property, but Python still knows about its correct use:
trying to set name
trying to access name
Name: "Bob"
{'_name': 'Bob'}
qml: {"objectName":""}
file:///Users/charles/Projects/qt/property-test/example.qml:9:9: Unable to assign [undefined] to QString
I'm scratching my head as to how QtCore.Property
is correctly setting up the Python property, but not the QML one. Is there something I'm missing about its implementation?