暂停工作线程并等待主线程中的事件

时间:2018-02-06 12:29:32

标签: python multithreading python-2.7 pyqt4 signals-slots

我们有一个执行不同查询的应用程序。它最多启动四个线程,并在它们上运行提取。

那部分看起来像这样:

    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_()

如何在特定点暂停线程,显示窗口(我相信它将返回主线程)并返回工作线程,传递按钮点击事件?

我读了一些关于信号的信息,但它似乎令人困惑,因为这是我第一次处理线程。

修改:在阅读完此问题:Similar question后,我将代码更改为:

内部的方法上
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'

2 个答案:

答案 0 :(得分:6)

以下是基于您问题中的代码的简单演示,它可以满足您的需求。除此之外,没有什么可说的,除了你需要通过信号(两个方向)在工作者和主线程之间进行通信。 mapStateToProps信号用于退出线程,这将停止显示警告消息_(key)

您看到错误的原因:

finished

是因为您尝试使用函数的 return 值(QThread: "Destroyed while thread is still running")来连接信号,而不是函数对象本身。您必须始终将python可调用对象传递给TypeError: connect() slot argument should be a callable or a signal, not `NoneType' 方法 - 其他任何内容都会引发None

请运行下面的脚本并确认它按预期工作。希望应该很容易看到如何使其适应您的真实代码。

connect

答案 1 :(得分:2)

如果您希望线程等待操作,请使用

连接线程中的信号
PyQt4.QtCore.Qt.BlockingQueuedConnection

作为旗帜。

现在我不明白为什么你需要线程如果你让他们等待,这会带来很多复杂性。对我来说,更好的解决方案是将您想要在线程中执行的任务切成小块。每次准备就绪时,您都可以询问用户是否还想要下一个。