在PySide的信号和槽页面 ,它说:“信号是由实例拥有的运行对象,他们不是类属性”。 显然,QObject的构造看起来对于信号,并将它们复制到对象实例的类属性。 这是我的测试程序确定。
从PySide进口QtCore
class Klass(QtCore.QObject):
lst = []
sig = QtCore.Signal(str)
def main():
obj1 = Klass()
obj2 = Klass()
print "id: obj1.lst = {}, obj1.sig = {}".format(id(obj1.lst), id(obj1.sig))
print "id: obj2.lst = {}, obj2.sig = {}".format(id(obj2.lst), id(obj2.sig))
print "id: klass.lst = {}, klass.sig = {}".format(id(Klass.lst), id(Klass.sig))
if __name__ == '__main__':
main()
在我的输出,你可以看到,现在有三个信号对象,而LST-成员的ID是两个对象和类相同。
id: obj1.lst = 4317739344, obj1.sig = 4297560376
id: obj2.lst = 4317739344, obj2.sig = 4297560400
id: klass.lst = 4317739344, klass.sig = 4317851072
隐式创建的对象的属性只是混乱,因此不良作风(恕我直言) 也许他们确实有这很好的理由,但我没有看到他们。 所以我的问题是:他们为什么要选择这种解决方案,而不是仅仅创造了信号在构造一个普通的属性?
他们不是拷贝 。 如果您检查这些类型,你会看到类属性是PySide.QtCore.Signal
和实例属性是PySide.QtCore.SignalInstance
。
print "type(obj1.sig): {}".format(type(obj1.sig))
print "type(obj2.sig): {}".format(type(obj2.sig))
print "type(Klass.sig): {}".format(type(Klass.sig))
# type(obj1.sig): <type 'PySide.QtCore.SignalInstance'>
# type(obj2.sig): <type 'PySide.QtCore.SignalInstance'>
# type(Klass.sig): <type 'PySide.QtCore.Signal'>
这是必要的,因为Qt的定义信号的方式。 Qt使用元对象系统来注册信号/插槽。 为了使这项工作,PySide做了一些“神奇”的幕后花絮,使元对象系统来注册你的自定义类属性的信号,并返回一个可用的信号( SignalInstance
具有相同的名称作为实例属性)。
原始Signal
依然存在,但与实例属性,而覆盖:
print "obj1.sig -> type: {}, id: {}".format(type(obj1.sig), id(obj1.sig))
print "obj1.__class__.sig -> type: {}, id: {}".format(type(obj1.__class__.sig), id(obj1.__class__.sig))
print "Klass.sig -> type: {}, id: {}".format(type(Klass.sig), id(Klass.sig))
# obj1.sig -> type: <type 'PySide.QtCore.SignalInstance'>, id: 40629904
# obj1.__class__.sig -> type: <type 'PySide.QtCore.Signal'>, id: 41556352
# Klass.sig -> type: <type 'PySide.QtCore.Signal'>, id: 41556352
文章来源: Why does PySide implicitely create object members from class members for Signals?