通过 PyQt signal/slot 连接时,对象被复制的频率是多少?

How often are objects copied when passing across PyQt signal/slot connections?

This interesting article 评估对象在 Qt 中通过 signal/slot 连接时被复制的频率。基本上,结果是当通过 C++ 中的 const 引用传递时,对象要么根本不复制(对于直接连接),要么复制一次(对于排队连接)。

PyQt 怎么样?同样的道理吗?对于Python个对象,做拷贝的时候是不是深拷贝?

我主要对 PyQt5 和 Python 3.

感兴趣

正如@ekhumoro 所建议的那样,我确实进行了尝试,令人惊讶的是,我得到的结果与在 C++ 中进行的测试所揭示的结果不同。基本上,我的测试表明:对象根本没有被复制,即使使用 QueuedConnection

跨线程边界传递也是如此

考虑以下测试代码:

class Object2(QObject):

    def __init__(self):
        super().__init__()

    @pyqtSlot(object)
    def slot(self, data):
        print("Received data %s in thread %s" % (data, QThread.currentThread()))
        while len(data) < 10:
            time.sleep(1)
            print("Current data is %s" % data)


class Object1(QObject):

    def __init__(self):
        super().__init__()

    sig = pyqtSignal(object)

    @pyqtSlot()
    def emit_in_thread(self):
        self.data = [1]
        print("Emitting data %s in thread %s" % (self.data, QThread.currentThread()))
        self.sig.emit(self.data)
        while len(self.data) < 10:
            time.sleep(1)
            self.data += [1]
            print("Modified data to %s" % self.data)

# App
q_app = QApplication(sys.argv)

# Setup
thread = QThread()
obj1 = Object1()
obj1.moveToThread(thread)
thread.start()
obj2 = Object2()
obj1.sig.connect(obj2.slot, type=Qt.QueuedConnection)

# Emit soon
QTimer.singleShot(200, obj1.emit_in_thread)

# Run event loop
sys.exit(q_app.exec_())

结果是:

Emitting data [1] in thread <PyQt5.QtCore.QThread object at 0x7f037619f948>
Received data [1] in thread <PyQt5.QtCore.QThread object at 0x7f037619faf8>
Current data is [1]
Modified data to [1, 1]
Current data is [1, 1]
Modified data to [1, 1, 1]
Current data is [1, 1, 1]
Modified data to [1, 1, 1, 1]
Current data is [1, 1, 1, 1]
...

这表明尽管发送插槽和接收插槽位于 不同的线程 中,但它们 共享 data通过 QueuedConnection 发送的对象。