我正在尝试使用多个线程实现一个程序。在主窗口的__init__
中,创建了线程。 GUI启动,而线程在后台运行。问题是它一直在崩溃。但是如果我用print语句添加/取消注释一行,程序就可以正常工作。
class TestThreadingWin(QtGui.QMainWindow):
def __init__(self, parent=rsui.getMayaMainWindow()):
''' Constructor '''
super(TestThreadingWin, self).__init__(parent)
self.setWindowTitle('Test Threading')
self.centralWidget = QtGui.QPlainTextEdit()
self.setCentralWidget(self.centralWidget)
self.centralWidget.appendPlainText("test")
numThreads = 7
self._threads = []
for i in range(numThreads):
#print self._threads # <-- Uncomment this line, and it works?!
testThread = QtCore.QThread()
# Keep a reference to the thread object or it will be deleted when
# it goes out of scope, even if it has not finished processing.
self._threads.append(testThread)
worker = TestThreadWorker(i)
worker.moveToThread(testThread)
worker.finishedProcessing.connect(self.updateStuff)
worker.finishedProcessing.connect(testThread.quit)
testThread.started.connect(worker.doStuff)
testThread.finished.connect(self.deleteThread)
testThread.start()
QtCore.QCoreApplication.processEvents()
print 'done creating all threads'
def deleteThread(self):
""" Destroy the thread object and remove the reference to it from the
self._threads list. """
print 'delete thread'
threadToDelete = self.sender()
threadIndex = self._threads.index(threadToDelete)
del self._threads[threadIndex]
threadToDelete.deleteLater()
def updateStuff(self, message):
self.centralWidget.appendPlainText(message)
class TestThreadWorker(QtCore.QObject):
finishedProcessing = QtCore.Signal(str)
def __init__(self, num):
super(TestThreadWorker, self).__init__()
self._num = num
def doStuff(self):
time.sleep(1)
choiceList = ['cat', 'bat', 'hat', 'tissue', 'paper', 'qwerty', 'mouse']
stuff = random.choice(choiceList)
stuff2 = '{0} {1}'.format(self._num, stuff)
self.finishedProcessing.emit(stuff2)
def openThreadingWin():
'''This ensures that only one instance of the UI is open at a time.'''
global testingThreadingWin
try:
testingThreadingWin.close()
testingThreadingWin.deleteLater()
except: pass
testingThreadingWin = TestThreadingWin()
testingThreadingWin.show()
打印声明会让它停止崩溃,这很奇怪。我在俯瞰什么?
答案 0 :(得分:0)
我终于通过使用QThreadPool来实现它。它为我管理线程,所以我不必担心尝试访问已被破坏的东西。主要差异:
__init__
函数,否则程序将崩溃。这是新代码:
class TestThreadPoolWin(QtGui.QMainWindow):
def __init__(self, parent=rsui.getMayaMainWindow()):
''' Constructor '''
super(TestThreadPoolWin, self).__init__(parent)
self.setWindowTitle('Test Threading')
self.centralWidget = QtGui.QPlainTextEdit()
self.setCentralWidget(self.centralWidget)
self.centralWidget.appendPlainText("test")
numThreads = 7
threadPool = QtCore.QThreadPool.globalInstance()
for i in range(numThreads):
runnable = TestRunnableWorker(i)
runnable.finishedProcessing.connect(self.updateStuff)
threadPool.start(runnable)
print 'done creating all threads'
def updateStuff(self, message):
self.centralWidget.appendPlainText(message)
class TestRunnableWorker(QtCore.QObject, QtCore.QRunnable):
finishedProcessing = QtCore.Signal(str)
def __init__(self, num, parent=None):
# Be sure to run the __init__ of both parent classes, or else you will
# get a crash.
QtCore.QObject.__init__(self, parent)
QtCore.QRunnable.__init__(self)
self._num = num
def run(self):
time.sleep(1)
choiceList = ['cat', 'bat', 'hat', 'tissue', 'paper', 'qwerty', 'mouse']
stuff = random.choice(choiceList)
stuff2 = '{0} {1}'.format(self._num, stuff)
self.finishedProcessing.emit(stuff2)
def openThreadPoolWin():
'''This ensures that only one instance of the UI is open at a time.'''
global testingThreadPoolWin
try:
testingThreadPoolWin.close()
testingThreadPoolWin.deleteLater()
except: pass
testingThreadPoolWin = TestThreadPoolWin()
testingThreadPoolWin.show()