【发布时间】:2020-06-29 00:27:50
【问题描述】:
我正在使用 PySide2 和 QML。当我在 Python 对象中定义 QtCore.Property 时,它成功地为 QML 以及 Python 属性 get/set 方法设置了访问权限。但是,我有一种情况,在定义类之后附加属性会很有用,但这并没有像我预期的那样工作。
首先,一个有效的例子:
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_())
还有一个简单的 QML 文件可供查看:
import QtQuick 2.15
import QtQuick.Window 2.15
Window {
visible: true
Component.onCompleted: { console.debug(JSON.stringify(backend)) }
Text { text: backend.name }
}
生成的图形窗口显示“Bob”,控制台输出包括:
trying to set name
trying to access name
Name: "Bob"
{'_name': 'Bob'}
qml: {"objectName":"","name":"Bob"}
然而,看起来只是一个简单的改变,事情变得令人困惑。我将 Python 类定义替换为:
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)
也就是说,getter、setter 和 Property 是在类定义之外定义的,并在事后附加到它上面。奇怪的是QML看不到Property,但是Python还是知道它的正确用法:
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
对于QtCore.Property 如何正确设置 Python 属性,而不是 QML 属性,我摸不着头脑。我对它的实现有什么遗漏吗?
【问题讨论】: