信号发出是否等待接收端完成?

Is a signal emit waits for the receiving end to finish?

PySide2信号发出是否等待接收端完成? 我一直认为 emit 只是发送一条消息并在那里结束,但是当我编写这段代码时我发现它不是

from PySide2.QtCore import QObject, Signal, Slot

class MySignal(QObject):
    data_signal = Signal(int)


class FirstClass:
    def __init__(self):
        self.sig = MySignal()
        self.data_signal = self.sig.data_signal

    def next_line(self):
        self.data_signal.emit(1)

class SecondClass:
    def __init__(self):
        self.count = 0
        self.first_class = FirstClass()
        self.first_class.data_signal.connect(self.get_data)
        self.get_data(1)

    @Slot(int)
    def get_data(self, data):
        print(self.count)

        if not self.count > 100:
            self.first_class.next_line()
            self.count += 1


sec = SecondClass()

我得到一长串 0(计数器从不增加) 最后这个错误

>>> RecursionError: maximum recursion depth exceeded while calling a Python object

在 PySide2 中执行此操作的最佳方法是什么,我知道对于此示例,如果我只是执行 yieldreturn 我不会遇到这个问题,但我想了解 PySide2 信号和插槽。

默认情况下,连接类型是Qt :: AutoConnection,它根据发送方和接收方属于哪个线程来决定连接类型。在这种情况下,它们都属于同一个线程,因此使用 Qt :: DirectConnection 连接将在发出信号的同时调用插槽,也就是说,您的代码等效于:

@Slot(int)
def get_data(self, data):
    print(self.count)

    if not self.count > 100:
        self.get_data(1)
        self.count += 1

而且显然该代码是递归的,因为 self.count += 1 从未执行过,因此 while 循环不会结束。

解决方案是让执行不是直接执行,而是稍后(当执行事件循环时)为此,连接必须是类型 Qt::QueuedConnection 并使用 QCoreApplication.

from PySide2.QtCore import QObject, Signal, Slot, QCoreApplication, Qt


class MySignal(QObject):
    data_signal = Signal(int)


class FirstClass:
    def __init__(self):
        self.sig = MySignal()
        self.data_signal = self.sig.data_signal

    def next_line(self):
        self.data_signal.emit(1)


class SecondClass:
    def __init__(self):
        self.count = 0
        self.first_class = FirstClass()
        self.first_class.data_signal.connect(self.get_data, Qt.QueuedConnection)
        self.get_data(1)

    @Slot(int)
    def get_data(self, data):
        print(self.count)

        if not self.count > 100:
            self.first_class.next_line()
            self.count += 1


app = QCoreApplication()
sec = SecondClass()
app.exec_()