【发布时间】:2014-05-25 10:28:23
【问题描述】:
我正在尝试实现一个使用 pyqt 进行线程化的基本示例,其中有一个文本框在处理一些代码时会定期更新。我试图删除任何不必要的依赖并尽可能地抽象代码,因此我只是将要在后台处理的代码替换为 while 循环,该循环在每个循环中发送数据以供文本框读取。但是,它不起作用,我不知道是什么导致 UI 挂断。我为当前线程 id 添加了调试语句,主类和工作类(在我的示例中称为 Process)都匹配
#!/zin/tools/bin/python
#vim:expandtab filetype=python nocindent sw=4
import sys, traceback
import os
import subprocess
import time
from PyQt4 import QtCore,QtGui
try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
_fromUtf8 = lambda s: s
class Process (QtCore.QObject):
processCmdDone = QtCore.pyqtSignal()
processdataReady = QtCore.pyqtSignal(str)
def __init__(self):
super(Process, self).__init__()
self.processdataReady.connect(self.debug)
def debug(self):
print "signal process data ready is invoked from within the process"
@QtCore.pyqtSlot()
@QtCore.pyqtSlot(str)
def execCmd(self):
print 'worker thread id :'+ str (QtCore.QThread.currentThreadId())
x = 0
while x < 100:
x+=1
self.processdataReady.emit(str(x)+'\n')
time.sleep(1)
self.processCmdDone.emit()
print "process ended"
class MainWindow (QtGui.QWidget):
def __init__(self,filename = None, parent=None):
super(MainWindow,self).__init__(parent)
self.transcript_textEdit = QtGui.QTextBrowser()
font = QtGui.QFont()
font.setPointSize(12)
self.transcript_textEdit.setFont(font)
self.transcript_textEdit.setObjectName(_fromUtf8("transcript_textEdit"))
self.layout = QtGui.QVBoxLayout(self)
self.layout.addWidget(self.transcript_textEdit)
self.run_pushButton = QtGui.QPushButton()
self.run_pushButton.setFont(font)
self.run_pushButton.setObjectName(_fromUtf8("run_pushButton"))
self.run_pushButton.setText('Run')
self.layout.addWidget(self.run_pushButton)
self.run_pushButton.clicked.connect(self.execCmdThreading)
def dataReady(self,text):
cursor = self.transcript_textEdit.textCursor()
cursor.movePosition(cursor.End)
cursor.insertText(str(text))
self.transcript_textEdit.ensureCursorVisible()
def execCmdThreading(self):
print 'gui thread id :'+ str (QtCore.QThread.currentThreadId())
thread = QtCore.QThread(self)
process_inst = Process()
process_inst.moveToThread(thread)
process_inst.processdataReady.connect(self.dataReady)
process_inst.processCmdDone.connect(thread.quit)
thread.finished.connect(thread.deleteLater)
process_inst.processCmdDone.connect(process_inst.deleteLater)
thread.started.connect(lambda: process_inst.execCmd())
thread.start()
if __name__=="__main__":
import sys
app = QtGui.QApplication(sys.argv)
MainWindowInst = MainWindow()
MainWindowInst.show()
sys.exit(app.exec_())
我只是创建一个文本框和一个按钮,在单击按钮时,会为类“Process”的实例创建一个线程,该线程被移动到线程并执行其方法“execCmd”。在执行 execCmd 方法时,会发出一个信号“processdataReady”,预计会在创建的文本框中显示文本。但是,代码似乎没有按预期运行,并且 UI 确实挂了。
我真的很感谢这里的任何人的帮助。
【问题讨论】: