QProgressDialog取消按钮有时无响应

时间:2014-03-10 18:52:49

标签: python qt pyside

我正在运行处理器繁重的操作并使用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次,这就解决了这个问题。这不是一个令人愉快的解决方案 - 一次性处理多少事件有限制吗?

1 个答案:

答案 0 :(得分:1)

您可能不会经常更新GUI以使取消按钮正常工作。

调用QApplication.instance().processEvents()是正确的做法,但绝对不是来自工作线程。它需要在GUI线程内调用(即在setImportProgress信号处理程序中)。

问题是:处理1%的帧需要多长时间?因为进度对话框在这段时间内没有响应。您需要找到一个更合适的步长值来发出progressChanged信号 - 一个足够短以保持取消按钮响应的信号,但不要太短以至于它会影响整体性能。