之前写过两篇博客,可以参考:
此篇博客是对上述两篇博客的补充。
参考这篇博客:http://themkbytes.blogspot.kr/2012/05/pyqt-gui-freeze-while-loops.html
得出如下结论,主线程中如果有一些耗时的计算,界面会暂时失去响应,那么,在计算的过程中,可以调用下界面的processEvents方法,让整个程序继续执行,处于事件循环中。
代码主要如下:
耗时导致界面失去响应的代码:
import itertools ,string x=1 file=open("file","w") while x<=200: it=itertools.product(string.printable,repeat=x) for i in it: ij="".join(i) file.write("ij"+"\n") x=x+1 file.close()
由于循环比较多,所以,导致界面失去响应,解决方案如下:
只需要在循环内部,加入:
gui=QtGui.Application.processEvents gui()
改造后的代码:
x = 1 file = open("file","w") gui() while x<=200: it=itertools.product(string.printable,repeat=x) time.sleep(0.1) gui() for i in it: ij="".join(i) time.sleep(0.001) gui() file.write("ij"+"\n") gui() x = x+1 gui() file.close() gui()
这样子界面就不会卡顿了。
补充:PyQt采用moveToThread解决卡顿问题
首先是一个worker类,主要是负责处理任务的:
其中Worker.py定义了两个信号,一个是madeProgress信号,一个是完成信号finished
class Worker(QtCore.QObject): madeProgress = QtCore.pyqtSignal([int]) finished = QtCore.pyqtSignal() def __init__(self, cmdlist): self.cmdlist = cmdlist def run(self): for icmd, cmd in enumerate(self.cmdlist): # execute your work # processCommand(cmd) # signal that we've made progress self.madeProgress.emit(icmd) # emit the finished signal - we're done self.finished.emit()
然后,通过moveToThread,我们将worker类放到线程里,通过thread类的started信号连接到worker类的运行函数(run方法),这样就使得worker类的run方法也处于线程里,通过run方法的信号释放,来绑定外部的槽函数。代码如下:
workerThread = QThread() workerObject = Worker(cmdlist) workerObject.moveToThread(workerThread) workerThread.started.connect(workerObject.run) workerObject.finished.connect(workerThread.quit) # create a progressbar with min/max according to # the length of your cmdlist progressBar = QProgressBar() progressBar.setRange(0, len(cmdlist)) # connect the worker's progress signal with the progressbar workerObject.madeProgress.connect(progressBar.setValue) # start the thread (starting your worker at the same time) workerThread.start()
上述例子即可完成线程操作方法,GUI便不会卡顿。
文章的脚注信息由WordPress的wp-posturl插件自动生成