Почему основной поток блокируется, если .connect принимает лямбда-функцию?

Я пытаюсь позволить кнопке запустить новый поток, который ничего не делает, кроме как спит в течение 30 секунд. Однако основной поток блокируется, если слот является лямбда-функцией. Кто-нибудь знает, почему это так, а не ведет себя так, как я ожидал? Вот мой код:

    # ...
    def setup(self):
        # ...
        self.pushButton_TestConnection.clicked.connect(self.process)

    def process(self):
        self.worker_thread = QtCore.QThread()
        self.worker = Worker()
        self.worker.moveToThread(self.worker_thread)
        self.worker_thread.started.connect(lambda: self.worker.sleep(30))

        self.worker_thread.start()

class Worker(QtCore.QObject):
    def sleep(self, secs):
        time.sleep(secs)

Он отлично работает со следующим

     self.worker_thread.started.connect(self.worker.sleep)

        self.worker_thread.start()

class Worker(QtCore.QObject):
    def sleep(self):
        time.sleep(30)

Спасибо


person Kar    schedule 20.02.2015    source источник
comment
Связано: stackoverflow.com/q/23317195/1994235   -  person three_pineapples    schedule 21.02.2015


Ответы (1)


В Qt поток, в котором выполняется код, определяется сходство с потоком объекта, получающего сигнал. Если вы вызываете метод объектов непосредственно из другого потока, он будет выполняться в вызывающем потоке, независимо от привязки к потоку вызываемого объекта.

Лямбда-выражения и другие вызываемые объекты Python не имеют привязки к потоку (в конце концов, они не являются объектами QObject, это просто приятная функция PyQt, позволяющая подключать сигнал к любому вызываемому объекту Python), поэтому они всегда будут выполняться в основном (GUI). ) thread.
Таким образом, в этом случае лямбда выполняется в потоке GUI, поэтому вызов worker.sleep также будет выполняться там и будет блокировать его до тех пор, пока вызов не вернется.

Чтобы это работало, вам нужно подключить сигнал started непосредственно к слоту объекта Worker или связаться с Worker, используя сигнал, который вы излучаете из лямбды.

person mata    schedule 20.02.2015