• <small id='3F3SG'></small><noframes id='3F3SG'>

  • <legend id='3F3SG'><style id='3F3SG'><dir id='3F3SG'><q id='3F3SG'></q></dir></style></legend>

      1. <tfoot id='3F3SG'></tfoot>

        • <bdo id='3F3SG'></bdo><ul id='3F3SG'></ul>
        <i id='3F3SG'><tr id='3F3SG'><dt id='3F3SG'><q id='3F3SG'><span id='3F3SG'><b id='3F3SG'><form id='3F3SG'><ins id='3F3SG'></ins><ul id='3F3SG'></ul><sub id='3F3SG'></sub></form><legend id='3F3SG'></legend><bdo id='3F3SG'><pre id='3F3SG'><center id='3F3SG'></center></pre></bdo></b><th id='3F3SG'></th></span></q></dt></tr></i><div id='3F3SG'><tfoot id='3F3SG'></tfoot><dl id='3F3SG'><fieldset id='3F3SG'></fieldset></dl></div>

        PyQt5 - QThread:在线程仍在运行时被销毁

        时间:2023-08-06

        <legend id='fUH9Q'><style id='fUH9Q'><dir id='fUH9Q'><q id='fUH9Q'></q></dir></style></legend>

          <i id='fUH9Q'><tr id='fUH9Q'><dt id='fUH9Q'><q id='fUH9Q'><span id='fUH9Q'><b id='fUH9Q'><form id='fUH9Q'><ins id='fUH9Q'></ins><ul id='fUH9Q'></ul><sub id='fUH9Q'></sub></form><legend id='fUH9Q'></legend><bdo id='fUH9Q'><pre id='fUH9Q'><center id='fUH9Q'></center></pre></bdo></b><th id='fUH9Q'></th></span></q></dt></tr></i><div id='fUH9Q'><tfoot id='fUH9Q'></tfoot><dl id='fUH9Q'><fieldset id='fUH9Q'></fieldset></dl></div>
        1. <small id='fUH9Q'></small><noframes id='fUH9Q'>

          <tfoot id='fUH9Q'></tfoot>

            <bdo id='fUH9Q'></bdo><ul id='fUH9Q'></ul>
                    <tbody id='fUH9Q'></tbody>
                  本文介绍了PyQt5 - QThread:在线程仍在运行时被销毁的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

                  问题描述

                  如果我在线程完成后再次尝试运行线程,我试图弄清楚为什么这段代码会崩溃.

                  I am trying to figure out why this code crashes if I try to run the threads for a second time once they are completed.

                  我第一次单击开始 5 个线程"时,它运行得很好并完成了.但如果我再次点击它.整个程序崩溃,我得到 QThread: Destroyed while thread is still running Error

                  The first time I click "Start 5 Threads" It runs just fine and finishes. But if I click it again. The entire program crashes and I get the QThread: Destroyed while thread is still running Error

                  此代码是在网络上找到的.我正在努力学习.

                  This code was found on the web. I am trying to learn from it.

                  import time
                  import sys
                  
                  from PyQt5.QtCore import QObject, QThread, pyqtSignal, pyqtSlot
                  from PyQt5.QtWidgets import QApplication, QPushButton, QTextEdit, QVBoxLayout, QWidget
                  
                  
                  def trap_exc_during_debug(*args):
                      # when app raises uncaught exception, print info
                      print(args)
                  
                  
                  # install exception hook: without this, uncaught exception would cause application to exit
                  sys.excepthook = trap_exc_during_debug
                  
                  
                  class Worker(QObject):
                      """
                      Must derive from QObject in order to emit signals, connect slots to other signals, and operate in a QThread.
                      """
                  
                      sig_step = pyqtSignal(int, str)  # worker id, step description: emitted every step through work() loop
                      sig_done = pyqtSignal(int)  # worker id: emitted at end of work()
                      sig_msg = pyqtSignal(str)  # message to be shown to user
                  
                      def __init__(self, id: int):
                          super().__init__()
                          self.__id = id
                          self.__abort = False
                  
                      @pyqtSlot()
                      def work(self):
                          """
                          Pretend this worker method does work that takes a long time. During this time, the thread's
                          event loop is blocked, except if the application's processEvents() is called: this gives every
                          thread (incl. main) a chance to process events, which in this sample means processing signals
                          received from GUI (such as abort).
                          """
                          thread_name = QThread.currentThread().objectName()
                          thread_id = int(QThread.currentThreadId())  # cast to int() is necessary
                          self.sig_msg.emit('Running worker #{} from thread "{}" (#{})'.format(self.__id, thread_name, thread_id))
                  
                          for step in range(100):
                              time.sleep(0.1)
                              self.sig_step.emit(self.__id, 'step ' + str(step))
                  
                              # check if we need to abort the loop; need to process events to receive signals;
                              app.processEvents()  # this could cause change to self.__abort
                              if self.__abort:
                                  # note that "step" value will not necessarily be same for every thread
                                  self.sig_msg.emit('Worker #{} aborting work at step {}'.format(self.__id, step))
                                  break
                  
                          self.sig_done.emit(self.__id)
                  
                      def abort(self):
                          self.sig_msg.emit('Worker #{} notified to abort'.format(self.__id))
                          self.__abort = True
                  
                  
                  class MyWidget(QWidget):
                      NUM_THREADS = 5
                  
                      # sig_start = pyqtSignal()  # needed only due to PyCharm debugger bug (!)
                      sig_abort_workers = pyqtSignal()
                  
                      def __init__(self):
                          super().__init__()
                  
                          self.setWindowTitle("Thread Example")
                          form_layout = QVBoxLayout()
                          self.setLayout(form_layout)
                          self.resize(400, 800)
                  
                          self.button_start_threads = QPushButton()
                          self.button_start_threads.clicked.connect(self.start_threads)
                          self.button_start_threads.setText("Start {} threads".format(self.NUM_THREADS))
                          form_layout.addWidget(self.button_start_threads)
                  
                          self.button_stop_threads = QPushButton()
                          self.button_stop_threads.clicked.connect(self.abort_workers)
                          self.button_stop_threads.setText("Stop threads")
                          self.button_stop_threads.setDisabled(True)
                          form_layout.addWidget(self.button_stop_threads)
                  
                          self.log = QTextEdit()
                          form_layout.addWidget(self.log)
                  
                          self.progress = QTextEdit()
                          form_layout.addWidget(self.progress)
                  
                          QThread.currentThread().setObjectName('main')  # threads can be named, useful for log output
                          self.__workers_done = None
                          self.__threads = None
                  
                      def start_threads(self):
                          self.log.append('starting {} threads'.format(self.NUM_THREADS))
                          self.button_start_threads.setDisabled(True)
                          self.button_stop_threads.setEnabled(True)
                  
                          self.__workers_done = 0
                          self.__threads = []
                          for idx in range(self.NUM_THREADS):
                              worker = Worker(idx)
                              thread = QThread()
                              thread.setObjectName('thread_' + str(idx))
                              self.__threads.append((thread, worker))  # need to store worker too otherwise will be gc'd
                              worker.moveToThread(thread)
                  
                              # get progress messages from worker:
                              worker.sig_step.connect(self.on_worker_step)
                              worker.sig_done.connect(self.on_worker_done)
                              worker.sig_msg.connect(self.log.append)
                  
                              # control worker:
                              self.sig_abort_workers.connect(worker.abort)
                  
                              # get read to start worker:
                              # self.sig_start.connect(worker.work)  # needed due to PyCharm debugger bug (!); comment out next line
                              thread.started.connect(worker.work)
                              thread.start()  # this will emit 'started' and start thread's event loop
                  
                          # self.sig_start.emit()  # needed due to PyCharm debugger bug (!)
                  
                      @pyqtSlot(int, str)
                      def on_worker_step(self, worker_id: int, data: str):
                          self.log.append('Worker #{}: {}'.format(worker_id, data))
                          self.progress.append('{}: {}'.format(worker_id, data))
                  
                      @pyqtSlot(int)
                      def on_worker_done(self, worker_id):
                          self.log.append('worker #{} done'.format(worker_id))
                          self.progress.append('-- Worker {} DONE'.format(worker_id))
                          self.__workers_done += 1
                          if self.__workers_done == self.NUM_THREADS:
                              self.log.append('No more workers active')
                              self.button_start_threads.setEnabled(True)
                              self.button_stop_threads.setDisabled(True)
                              # self.__threads = None
                  
                      @pyqtSlot()
                      def abort_workers(self):
                          self.sig_abort_workers.emit()
                          self.log.append('Asking each worker to abort')
                          for thread, worker in self.__threads:  # note nice unpacking by Python, avoids indexing
                              thread.quit()  # this will quit **as soon as thread event loop unblocks**
                              thread.wait()  # <- so you need to wait for it to *actually* quit
                  
                          # even though threads have exited, there may still be messages on the main thread's
                          # queue (messages that threads emitted before the abort):
                          self.log.append('All threads exited')
                  
                  
                  if __name__ == "__main__":
                      app = QApplication([])
                  
                      form = MyWidget()
                      form.show()
                  
                      sys.exit(app.exec_())
                  

                  推荐答案

                  通过将他作为父母传递给自己来解决问题.你必须改变:

                  The problem is solved by passing him as a parent to self. You must change:

                  thread = QThread()
                  

                  到:

                  thread = QThread(parent=self)
                  

                  这篇关于PyQt5 - QThread:在线程仍在运行时被销毁的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持html5模板网!

                  上一篇:多重继承元类冲突 下一篇:PyQt5中带框架的自定义标题栏

                  相关文章

                  最新文章

                1. <tfoot id='NftAb'></tfoot>

                    <bdo id='NftAb'></bdo><ul id='NftAb'></ul>

                2. <i id='NftAb'><tr id='NftAb'><dt id='NftAb'><q id='NftAb'><span id='NftAb'><b id='NftAb'><form id='NftAb'><ins id='NftAb'></ins><ul id='NftAb'></ul><sub id='NftAb'></sub></form><legend id='NftAb'></legend><bdo id='NftAb'><pre id='NftAb'><center id='NftAb'></center></pre></bdo></b><th id='NftAb'></th></span></q></dt></tr></i><div id='NftAb'><tfoot id='NftAb'></tfoot><dl id='NftAb'><fieldset id='NftAb'></fieldset></dl></div>

                      <small id='NftAb'></small><noframes id='NftAb'>

                      <legend id='NftAb'><style id='NftAb'><dir id='NftAb'><q id='NftAb'></q></dir></style></legend>