【问题标题】:Python - PyQt : Continue after a QThread is finishedPython - PyQt:QThread 完成后继续
【发布时间】:2018-09-29 01:15:11
【问题描述】:

我在 QThread 中有一个 for 循环,它是通过一个按钮从主 GUI 启动的。当 for 循环结束时,我想回到主线程(在 Gui 类中)并做其他事情。 据我了解,应该使用 join 方法等待线程完成。就我而言,MyThread 似乎永远不会完成。

import sys
from PyQt5 import QtCore
import PyQt5.QtWidgets as QtW
from PyQt5.QtCore import QThread

class MyWindow(QtW.QMainWindow):

  def __init__(self):
    super().__init__()
    self.setWindowTitle('MyWindow')
    self._main = QtW.QWidget()
    self.setCentralWidget(self._main) 
    self.button = QtW.QPushButton('Do it', self)
    self.button.clicked.connect(self.MyMethod)
    self.layout = QtW.QGridLayout(self)
    self.layout.addWidget(self.button)
    self.setLayout(self.layout)


  def MyMethod(self):
    self.n = 5
    self.loadthread = MyThread(self.n)
    self.loadthread.start()
    self.loadthread.join() # Will wait for the thread until it finishes its task
    print('thread finished')


class MyThread(QThread):

    def __init__(self, n):
        QThread.__init__(self)
        self.n = n

    def run(self):
        for i in range(self.n):
            print(i)
        print('cycle finished')


if __name__ == '__main__':
    app = QtCore.QCoreApplication.instance() # checks if QApplication already exists 
    if app is None: # create QApplication if it doesnt exist 
        app = QtW.QApplication(sys.argv)
    mainGui = MyWindow()
    mainGui.show()
    app.aboutToQuit.connect(app.deleteLater)
    app.exec_()

cos的输出是

0
1
2
3
4
cycle finished

并且永远无法到达print('thread finished')

【问题讨论】:

    标签: python multithreading pyqt pyqt5 qthread


    【解决方案1】:

    QThread 没有join() 方法,因此您的应用程序应该意外退出并指向以下错误消息。

    QLayout: Attempting to add QLayout "" to MyWindow "", which already has a layout
    QWidget::setLayout: Attempting to set QLayout "" on MyWindow "", which already has a layout
    0
    1
    2
    3
    Traceback (most recent call last):
      File "main.py", line 24, in MyMethod
        self.loadthread.join() # Will wait for the thread until it finishes its task
    AttributeError: 'MyThread' object has no attribute 'join'
    4
    cycle finished
    Aborted (core dumped)
    

    如果你想在执行完线程后执行某个任务,你必须使用QThreadfinished信号:

    import sys
    from PyQt5 import QtCore, QtWidgets
    
    
    class MyWindow(QtWidgets.QMainWindow):
        def __init__(self):
            super().__init__()
            self.setWindowTitle('MyWindow')
            self._main = QtWidgets.QWidget()
            self.setCentralWidget(self._main) 
            self.button = QtWidgets.QPushButton('Do it')
            self.button.clicked.connect(self.my_method)
            layout = QtWidgets.QGridLayout(self._main)
            layout.addWidget(self.button)
            layout.addWidget(self.button)
    
        @QtCore.pyqtSlot()
        def my_method(self):
            self.n = 5
            self.loadthread = MyThread(self.n, self)
            self.loadthread.finished.connect(self.on_finished)
            self.loadthread.start()
    
        @QtCore.pyqtSlot()
        def on_finished(self):
            print('thread finished')
    
    
    class MyThread(QtCore.QThread):
        def __init__(self, n, parent=None):
            QtCore.QThread.__init__(self, parent)
            self.n = n
    
        def run(self):
            for i in range(self.n):
                print(i)
            print('cycle finished')
    
    
    if __name__ == '__main__':
        app = QtWidgets.QApplication.instance()
        if app is None: 
            app = QtWidgets.QApplication(sys.argv)
        mainGui = MyWindow()
        mainGui.show()
        app.aboutToQuit.connect(app.deleteLater)
        sys.exit(app.exec_())
    

    【讨论】:

    • 谢谢!这很有启发性!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-02-03
    • 1970-01-01
    • 2013-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-04
    相关资源
    最近更新 更多