类型:Python,C++ & Qt4,创建时间:Jan. 6, 2015, 5:08 p.m.
标题无“转载”即原创文章,版权所有。转载请注明来源:http://hgoldfish.com/blogs/article/97/。
之前我在Python中使用线程的技巧一文中提到,尽量不要在 PyQt 里面使用QThread
,但是当时没有给出示例程序。这里补上一个会引起Python崩溃的代码。其实主要原因是QThread
被强制关闭的时候会引起Python崩溃。
from __future__ import unicode_literals from __future__ import print_function from PyQt4.QtCore import * from PyQt4.QtGui import * class Worker(QObject): @pyqtSlot() def doSomething(self): i = 0 while True: i += 1 t = i * 23729378 + 9273947297123123124 class MainWindow(QPushButton): def __init__(self): super(MainWindow, self).__init__() self.setText("click me again and again.") self.clicked.connect(self.startNewThread) self.workers = [] def startNewThread(self, checked): self.thread = QThread() worker = Worker() worker.moveToThread(self.thread) self.workers.append(worker) self.thread.start() QTimer.singleShot(0, worker, SLOT("doSomething()")) def test(): app = QApplication([]) w = MainWindow() w.show() try: return app.exec_() except AttributeError: return getattr(app, "exec")() if __name__ == "__main__": test()
使劲点击按钮,这段代码就会不断打印出QThread: Destroyed while thread is still running
。通常情况下,Python会报一个段错误,然后退出。不过,经过测试,并非所有的PyQt版本都会立即异常报错。老鱼在使用 PyQt 4.11.1 + Python 2.7.8 (openSUSE) 的时候点击十几次就报错退出了。在 Windows 里面,即使没有Worker
,把startNewThread()
写成这样子,点击两三次也会异常退出:
def startNewThread(self, checked): self.thread = QThread() self.thread.start()
标题无“转载”即原创文章,版权所有。转载请注明来源:http://hgoldfish.com/blogs/article/97/。
叁拾掃地肆拾不獲(Jan. 6, 2015, 8:10 p.m.)
不是QThread 不可用,而是博主用错了。
老鱼(Jan. 7, 2015, 11:35 a.m.)
QThread
的正确用法就是如此。如果非要写QThread(self)
的话,你就必须再写一个QThread::deleteLater()
,不然内存泄露。
叁拾掃地肆拾不獲(Jan. 7, 2015, 11:52 a.m.)
不用 deleteLater,而应该把 self.thread = QThread() 移到 init 中,这只因为每次创建一个新的qthread,旧 qthread 被 gc 掉的缘故。
Louis(Nov. 12, 2018, 3:42 a.m.)
Good