为什么 PySide 隐式地从 Signals 的类成员创建对象成员? [英] Why does PySide implicitely create object members from class members for Signals?

查看:40
本文介绍了为什么 PySide 隐式地从 Signals 的类成员创建对象成员?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

On the PySide signals and slots page it says: "Signals are runtime objects owned by instances, they are not class attributes". Apparently the QObject constructor looks in the class attributes for Signals and copies them to the object instance. This is confirmed by my test program.

从 PySide 导入 QtCore

from PySide import 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-member 的 id 对于对象和类都是相同的.

In my output you can see that there are now three signal objects whereas the id of lst-member is the same for both objects and the class.

id: obj1.lst  = 4317739344, obj1.sig  = 4297560376
id: obj2.lst  = 4317739344, obj2.sig  = 4297560400
id: klass.lst = 4317739344, klass.sig = 4317851072

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

Implicitly creating the object attributes is just confusing and therefore bad style (IMHO). Maybe they do have good reasons for this but I don't see them. So my question is: why did they choose this solution instead of just creating the signal as a regular attribute in the constructor?

推荐答案

它们不是副本.如果您检查它们的类型,您将看到类属性为 PySide.QtCore.Signal,实例属性为 PySide.QtCore.SignalInstance.

They are not copies. If you check the type of those, you'll see that the class attribute is PySide.QtCore.Signal and the instance attribute is 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)实例属性.

This is necessary because of the way Qt defines signals. Qt uses Meta-Object System to register signals/slots. In order to make this work, PySide does some 'magic' behind the curtain to register your custom class-attribute signal with Meta-Object System and return you a usable signal (SignalInstance) with the same name as instance attribute.

原始 Signal 仍然存在,但被实例属性覆盖:

Original Signal is still there, but rather overridden with the instance attribute:

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

这篇关于为什么 PySide 隐式地从 Signals 的类成员创建对象成员?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆