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

Posted

技术标签:

【中文标题】QThread:在线程仍在运行时被销毁【英文标题】:QThread: Destroyed while thread is still running 【发布时间】:2013-03-20 03:03:16 【问题描述】:

我在 python 中遇到 QThreads 问题。我想更改标签的背景颜色。 但是我的应用程序在启动时崩溃了。 “”

   class MainWindow(QMainWindow):
      def __init__(self):
          QMainWindow.__init__(self)
          self.ui = Ui_MainWindow()
          self.ui.setupUi(self)

          statusTh = statusThread(self)
          self.connect(statusTh, SIGNAL('setStatus'), self.st, Qt.QueuedConnection)
          statusTh.start()

      def st(self):
          if self.status == 'ON':
              self.ui.label.setStyleSheet('background-color:green')
          else:
              self.ui.label.setStyleSheet('background-color:red')

  class statusThread(QThread):
      def __init__(self, mw):
          super(statusThread, self).__init__()

      def run(self):
          while True:
              time.sleep(1)
              self.emit(SIGNAL('setStatus'))

  if __name__ == "__main__":
      app = QApplication(sys.argv)
      main_window = MainWindow()
      main_window.show()
      sys.exit(app.exec_())

【问题讨论】:

一个Qt风格的解决方案,指定主窗口为statusTh的父窗口,即super(statusThread, self).__init__(mw) 非常感谢。它现在正在工作 仅供参考,这基本上是一样的:在这种情况下,父级将保留对线程实例的引用,因此不会被垃圾回收。 谁能解释一下,Qt.QueuedConnection 在上面的问题中是什么意思? 所以基本上这只是一个错字? 【参考方案1】:

在创建线程后,您没有存储对线程的引用,这意味着在程序离开MainWindows __init__ 后的某个时间,它将被垃圾收集(即销毁)。只要线程正在运行,您至少需要存储它,例如使用self.statusTh

self.statusTh = statusThread(self)
self.connect(self.statusTh, SIGNAL('setStatus'), self.st, Qt.QueuedConnection)
self.statusTh.start()

【讨论】:

对不起,我是 Python 新手。我无法理解。我如何需要存储参考? 正如我在回答中所写的那样。通过将statusThread(self) 的实例分配给局部变量(即前面没有self.),当局部变量超出范围时(当__init__MainWindow完结了)。如果将引用存储在MainWindow类的成员变量中(即前面有self.),当__init__完成时它不会超出范围,导致线程对象不是垃圾收集。 我会投 10 票!很好的答案 - 为我节省了很多时间和悲伤!我认为您也应该将评论文本移至答案。 对不起,但是如果你 dont want 来存储引用 - 是否有任何方法可以创建对对象(线程)的新引用?我有很多方法需要同时工作。

以上是关于QThread:在线程仍在运行时被销毁的主要内容,如果未能解决你的问题,请参考以下文章

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

Qt:qthread在关闭期间线程仍在运行时被破坏

QProcess 和 shell:进程仍在运行时被销毁

QtConcurrent::run => QWaitCondition: 在线程仍在等待时被销毁

UITableViewDelegate dealloc 方法在应用程序仍在运行时被调用

如果在其他线程仍在运行时调用exit会发生什么?