在 QTimer Singleshot 之后终止 QThread

Posted

技术标签:

【中文标题】在 QTimer Singleshot 之后终止 QThread【英文标题】:Terminate a QThread after QTimer Singleshot 【发布时间】:2020-03-12 13:41:02 【问题描述】:

我有一个问题。我正在运行一个 PyQt5 表单,该表单运行一个名为 Task() 的工作程序(我不会详细介绍它的代码,但它基本上只是在 QThread 中返回一个值到 QLabel),如下所示:

class Menu(QMainWindow):
    def __init__(self, workers):
        super().__init__()
        self.central_widget = QWidget()               
        self.setCentralWidget(self.central_widget)    
        lay = QVBoxLayout(self.central_widget)
        self.setFixedSize(500, 350)
        Pic = QLabel(self)
        self.Total = QLabel("Total: <font color='orange'>%s</font>" % (to_check()), alignment=QtCore.Qt.AlignHCenter)
        lay.addWidget(self.Total)
        thread = QtCore.QThread(self)
        thread.start()
        self.worker = Task()
        self.worker.moveToThread(thread)
        self.worker.totalChanged.connect(self.updateTotal)
        QtCore.QTimer.singleShot(0, self.worker.dostuff)
        thread.finished.connect(self.terminate)


    @QtCore.pyqtSlot(int)
    def updateTotal(self, total):
        self.Total.setText("Total: <font color='orange'>%s</font>" % (total))  

    def terminate(self):
        print("FINISHED")
        self.worker.quit()
        self.worker.wait()
        self.close()

我希望程序在 Task().dostuff() 函数完成后调用 terminate 插槽(并基本上终止线程和函数) - 但我似乎无法让它工作。

我不知道如何通过QTimer.singleshot返回主函数。

【问题讨论】:

【参考方案1】:

不应该需要计时器。使用线程的started信号启动worker,给worker类添加finished信号退出线程:

class Task(QtCore.QObject):
    totalChanged = QtCore.pyqtSignal(int)
    finished = QtCore.pyqtSignal()

    def dostuff(self):
        # do stuff ...
        self.finished.emit()

class Menu(QtWidgets.QMainWindow):
    def __init__(self, workers):
        super().__init__()
        ...
        self.thread = QtCore.QThread()
        self.worker = Task()
        self.worker.moveToThread(self.thread)
        self.worker.totalChanged.connect(self.updateTotal)
        self.worker.finished.connect(self.thread.quit)
        self.thread.started.connect(self.worker.dostuff)
        self.thread.start()

【讨论】:

以上是关于在 QTimer Singleshot 之后终止 QThread的主要内容,如果未能解决你的问题,请参考以下文章

QTimer::singleShot 在 qkeyevent 中不起作用

QTimer::singleShot()函数使用

QTimer::singleShot(0, object SLOT(obj_slot())) 做啥?

QTimer::singleShot 仅在间隔为 0 时调用 lambda

PyQT实时显示串口数据在QtCore.QTimer.singleShot()上抛出最大递归深度超出异常

当 singleShot 为 True 时,QTimer 永远不会触发超时 [关闭]