簡體   English   中英

暫停工作線程並等待主線程中的事件

[英]Pause worker thread and wait for event from main thread

我們有一個執行不同查詢的應用程序。 它最多啟動四個線程,並在它們上運行提取。

那部分看起來像這樣:

    if len(self.threads) == 4:
        self.__maxThreadsMsg(base)
        return False
    else:
        self.threads.append(Extractor(self.ui, base))
        self.threads[-1].start()
        self.__extractionMsg(base)
        return True

我們的Extractor類繼承了QThread

class Extractor(QThread):
    def init(self, ui, base):
        QThread.__init__(self)
        self.ui = ui
        self.base = base

    def run(self):
        self.run_base(base)

self.ui設置為Ui_MainWindow()

class Cont(QMainWindow):
    def __init__(self, parent=None):
        QWidget.__init__(self,parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

在繼續之前,有一個特定的基礎將數據發送給用戶(返回主窗口)(在這種情況下,帶有兩個按鈕的彈出窗口):

#This code is in the main file inside a method, not in the Extractor class
msg_box = QMessagebox()
msg_box.setText('Quantity in base: '.format(n))
msg_box.setInformativeText('Would you like to continue?')
msg_box.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel)
signal = msg_box.exec_()

如何在特定點暫停線程,顯示窗口(我相信將返回主線程)並返回工作線程,傳遞按鈕點擊事件?

我讀了一些關於信號的內容,但它似乎令人困惑,因為這是我第一次處理線程。

編輯:閱讀此問題后: 類似問題 ,我將代碼更改為:

Cont類的內部方法

thread = QThread(self)
worker = Worker()

worker.moveToThread(thread)
worker.bv.connect(self.bv_test)

thread.started.connect(worker.process()) # This, unlike in the linked question.. 
#doesn't work if I remove the parentheses of the process function. 
#If I remove it, nothing happens and I get QThread: "Destroyed while thread is still running"

thread.start()

@pyqtSlot(int)
def bv_test(self, n):
    k = QMessageBox()
    k.setText('Quantity: {}'.format(n))
    k.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
    ret = k.exec_()
    return ret

這是Worker類:

class Worker(QObject):

    #Signals
    bv = pyqtSignal(int)

    def process(self):
        self.bv.emit(99)

現在我只需要弄清楚如何將ret值發送回工作線程,以便啟動第二個進程。 我也一直收到這個錯誤:

TypeError: connect() slot argument should be a callable or a signal, not 'NoneType'

下面是一個基於您的問題中的代碼的簡單演示,它可以滿足您的需求。 除此之外,沒有什么可說的,除了你需要通過信號(兩個方向)在工作者和主線程之間進行通信。 finished信號用於退出線程,這將停止警告消息QThread: "Destroyed while thread is still running"QThread: "Destroyed while thread is still running"被顯示。

您看到錯誤的原因:

TypeError: connect() slot argument should be a callable or a signal, not `NoneType'

是因為您嘗試使用函數的返回值( None )來連接信號,而不是函數對象本身。 您必須始終將python可調用對象傳遞給connect方法 - 其他任何東西都會引發TypeError

請運行下面的腳本並確認它按預期工作。 希望應該很容易看到如何使其適應您的真實代碼。

from PyQt4.QtCore import *
from PyQt4.QtGui import *

class Cont(QWidget):
    confirmed = pyqtSignal()

    def __init__(self):
        super(Cont, self).__init__()
        self.thread = QThread()
        self.worker = Worker()
        self.worker.moveToThread(self.thread)
        self.worker.bv.connect(self.bv_test)
        self.worker.finished.connect(self.thread.quit)
        self.confirmed.connect(self.worker.process_two)
        self.thread.started.connect(self.worker.process_one)
        self.thread.start()

    def bv_test(self, n):
        k = QMessageBox(self)
        k.setAttribute(Qt.WA_DeleteOnClose)
        k.setText('Quantity: {}'.format(n))
        k.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
        if k.exec_() == QMessageBox.Yes:
            self.confirmed.emit()
        else:
            self.thread.quit()

class Worker(QObject):
    bv = pyqtSignal(int)
    finished = pyqtSignal()

    def process_two(self):
        print('process: two: started')
        QThread.sleep(1)
        print('process: two: finished')
        self.finished.emit()

    def process_one(self):
        print('process: one: started')
        QThread.sleep(1)
        self.bv.emit(99)
        print('process: one: finished')

app = QApplication([''])
win = Cont()
win.setGeometry(100, 100, 100, 100)
win.show()
app.exec_()

如果您希望線程等待操作,請使用線程連接到線程的信號

PyQt4.QtCore.Qt.BlockingQueuedConnection

作為旗幟。

現在我不明白為什么你需要線程如果你讓他們等待,這會帶來很多復雜性。 對我來說,更好的解決方案是將您想要在線程中執行的任務切成小塊。 每次准備就緒時,您都可以詢問用戶是否還想要下一個。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM