Skip to main content
 首页 » 编程设计

python之QProgressDialog 取消按钮有时没有响应

2025年05月04日23JeffreyZhao

我正在运行处理器繁重的操作并使用 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的run class和cancel slot。

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 的信息后在其他地方,我连续写了 10 次 QApplication.instance().processEvents(),这就解决了问题。这不是一个令人愉快的解决方案 - 一次处理的事件数量是否有限制?

请您参考如下方法:

您可能没有足够频繁地更新 GUI 以使取消按钮正常工作。

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

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