为什么PySide会隐含地从类成员为Signals创建对象成员?

tit*_*jan 4 signals pyside

PySide信号和插槽页面上,它说:"信号是实例拥有的运行时对象,它们不是类属性".显然,QObject构造函数在Signals的类属性中查找并将它们复制到对象实例.我的测试程序证实了这一点.

来自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()
Run Code Online (Sandbox Code Playgroud)

在我的输出中,您可以看到现在有三个信号对象,而lst-member的id对于对象和类都是相同的.

id: obj1.lst  = 4317739344, obj1.sig  = 4297560376
id: obj2.lst  = 4317739344, obj2.sig  = 4297560400
id: klass.lst = 4317739344, klass.sig = 4317851072
Run Code Online (Sandbox Code Playgroud)

隐式创建对象属性只是令人困惑,因此风格很差(恕我直言).也许他们确实有充分的理由,但我没有看到他们.所以我的问题是:为什么他们选择这个解决方案而不是仅仅在构造函数中创建信号作为常规属性?

Ava*_*ris 6

它们不是副本.如果检查那些类型,您将看到class属性是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'>
Run Code Online (Sandbox Code Playgroud)

由于Qt定义信号的方式,这是必要的.Qt使用元对象系统来注册信号/插槽.为了使这项工作,PySide在幕后做了一些"魔术",用Meta-Object System注册你的自定义类属性信号,并返回一个SignalInstance与实例属性同名的可用信号().

Original Signal仍然存在,但是被instance属性覆盖:

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
Run Code Online (Sandbox Code Playgroud)