我正在运行处理器繁重的操作并使用QProgressDialog向用户报告。但是,取消按钮工作不正常 - 有时它会在整个运行过程中被忽略,有时它会响应,但只有在进度中的某个点之后(这一点也不一致)。在我看来好像事件循环没有被调用,所以我调用了QApplication.instance()。processEvents()但是仍然存在不稳定的行为。
这是完成工作的功能。
def import(self):
imp = worker()
imp.progressChanged.connect(self.setImportProgress)
self.progress.canceled.connect(imp.cancel)
imp.run()
self.progress.setValue(100) #Ensures we reach the end, in case of rounding errors
@Slot(int)
def setImportProgress(self,p):
self.progress.setValue(p)
QApplication.instance().processEvents()
这是worker的运行类和取消槽。
def run(self):
frameCount = 0
hundredth = self.numFrames/100 #Used to output percentages
while True:
ret, frame = self.cam.read()
if not ret: #Breaks when the last frame is reached
break
if frameCount >= self.start:
self.doWorkOnFrame()
#Output the percentage completed
if frameCount % hundredth == 0:
self.progressChanged.emit(frameCount/hundredth)
@QtCore.Slot()
def cancel(self):
print "Cancel Pressed"
我意识到取消槽目前没有做任何事情,我只是想在实现实际功能之前让它一直激活。我确实得到了“取消按下”输出,所以我知道信号槽连接设置正确,按下按钮时它不一致。
我意识到存在类似的问题,但我找不到完全相同的问题,类似问题的解决方案似乎也不起作用。对不起,如果这是重复的。
编辑 - 在其他地方读到similar problem时,我连续写了QApplication.instance().processEvents()
10次,这就解决了这个问题。这不是一个令人愉快的解决方案 - 一次性处理多少事件有限制吗?
答案 0 :(得分:1)
您可能不会经常更新GUI以使取消按钮正常工作。
调用QApplication.instance().processEvents()
是正确的做法,但绝对不是来自工作线程。它需要在GUI线程内调用(即在setImportProgress
信号处理程序中)。
问题是:处理1%的帧需要多长时间?因为进度对话框在这段时间内没有响应。您需要找到一个更合适的步长值来发出progressChanged
信号 - 一个足够短以保持取消按钮响应的信号,但不要太短以至于它会影响整体性能。