Kenapa thread utama diblokir jika .connect mengambil fungsi lambda?

Saya mencoba membiarkan tombol memutar utas baru yang tidak melakukan apa pun selain tidur selama 30 detik. Namun, thread utama diblokir jika slotnya adalah fungsi lambda. Adakah yang tahu mengapa hal ini terjadi dan tidak berperilaku seperti yang saya harapkan? Ini kode saya:

    # ...
    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)

Ini berfungsi baik dengan yang berikut ini

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

        self.worker_thread.start()

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

Terima kasih


person Kar    schedule 20.02.2015    source sumber
comment
Terkait: stackoverflow.com/q/23317195/1994235   -  person three_pineapples    schedule 21.02.2015


Jawaban (1)


Di Qt, thread tempat kode dieksekusi ditentukan oleh afinitas thread dari objek yang menerima sinyal. Jika Anda memanggil metode objek secara langsung dari thread berbeda, metode tersebut akan dieksekusi di thread pemanggil, tidak peduli afinitas thread dari objek yang dipanggil.

Lambdas dan callable python lainnya tidak memiliki afinitas thread (bagaimanapun juga, mereka bukan QObjects, ini hanya fitur bagus dari PyQt yang memungkinkan Anda menghubungkan sinyal ke callable python apa pun), sehingga mereka akan selalu dieksekusi di main (GUI ) thread.
Jadi dalam hal ini lambda dieksekusi di thread GUI, sehingga panggilan worker.sleep juga akan dieksekusi di sana dan akan memblokirnya hingga panggilan tersebut kembali.

Agar ini berfungsi, Anda perlu menghubungkan sinyal started langsung ke slot objek Worker, atau berkomunikasi dengan Worker menggunakan sinyal yang Anda pancarkan dari lambda.

person mata    schedule 20.02.2015