当通过 PyQt 信号/槽连接传递时,对象被复制的频率是多少?

And*_*bis 4 python pyqt signals-slots pyqt5

这篇有趣的文章评估了在 Qt 中通过信号/槽连接传递对象时复制对象的频率。基本上,结果是,当在 C++ 中通过 const 引用传递时,对象要么根本不被复制(对于直接连接),要么被复制一次(对于排队连接)。

PyQt 怎么样?这同样成立吗?对于Python对象,当进行复制时,是否是深复制?

我主要对 PyQt5 和 Python 3 感兴趣。

And*_*bis 6

正如 @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_())
Run Code Online (Sandbox Code Playgroud)

结果是:

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

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