dav*_*ave 3 python qt pyqt pyside
    progress = QtGui.QProgressDialog("Parsing Log", "Stop", 0,numberOfLinesInFile , self)
    progress.setWindowModality(QtCore.Qt.WindowModal)
    for lineNumber, line in enumerate(file):
        # yield a bit to the Qt UI handler
        QtGui.QApplication.processEvents()
        progress.setValue(lineNumber + 1) # lineNumber is zero-based so need the plus one to match the more literal numberOfLinesInFile
        if progress.wasCanceled():
            progressWasCancelled = True
            break
        # ...read and parse lines from file (20mb takes ~10 seconds)
    # crank the progress bar through to completion to get rid of it
    # this seems to forgo the opportunity to use progress.wasCanceled() subsequently?
    progress.setValue(numberOfLinesInFile)
    if not progressWasCancelled:
        self.updateTable(self.requestRoster)
Run Code Online (Sandbox Code Playgroud)
此后,无论进度对话框是否被取消,进度对话框都是隐藏的(它会向上滑动回到工具栏中)。但是,如果我切换了应用程序(在Mac上为“命令选项卡”),然后又切换回了我的应用程序,则QProgressDialog的幽灵将出现在主应用程序窗口的前面!它的进度条为100%,停止按钮为蓝色,但没有脉动。它没有反应。如果我移动应用程序窗口,它将消失。
如果我在progress.setValue(numberOfLinesInFile)之后调用progress.destroy()似乎有帮助。但是似乎很担心从文档中复制示例并被咬住,而且我不知道destroy()的后果。
我使用的是PySide,后来我改用了PyQt。
另外,有时会progress.setValue(numberOfLinesInFile)导致后续的读取progress.wasCancelled()返回false(但有时会返回true!),这就是我设置自己的的原因progressWasCancelled。它的随机性令人不安。
我在Mac 10.6.8,Qt 4.8.2,Python 2.7上。尝试使用PySide 1.1.0和PyQt 4.9.4。
我做错了吗?
我无法在Mac上进行测试,但会尝试提出一些建议,以帮助解决您的问题。
首先,如果使用模式进度对话框,则无需调用processEvents(),因为该对话框将自行处理。
其次,您的代码中的这一行:
    progress.setValue(lineNumber + 1)
Run Code Online (Sandbox Code Playgroud)
是有问题的,因为要引用Qt docs:
为了使进度对话框按预期方式工作,应首先将此属性设置为0,最后将其设置为QProgressDialog :: maximum() ; 您可以在之间任意多次调用setValue()。
因此,您应该progress.setValue(0)在循环之前调用,或者只是避免完全添加偏移量。同样,在最后一次迭代中,lineNumber + 1将等于最大值,这将在该点重置对话框(除非将autoReset设置为False)。因此,Qt示例setValue(maximum) 在循环完成后调用。
最后,调用destroy()或deleteLater()完成进度对话框后都没有问题-实际上,这是一个好主意。当您传递self给QProgressDialog构造函数时,它将成为对话框的父级并保留对其的引用。因此,除非您明确删除它,否则每次您调用使用它的函数时,都会添加一个新的子对话框(及其所有子对象)(这可能会浪费大量内存)。
这是一个可能会改进的演示脚本:
import sys, time
from PyQt4 import QtGui, QtCore
class Window(QtGui.QWidget):
    def __init__(self):
        QtGui.QWidget.__init__(self)
        self.button = QtGui.QPushButton('Test', self)
        self.button.clicked.connect(self.handleButton)
        layout = QtGui.QVBoxLayout(self)
        layout.addWidget(self.button)
    def handleButton(self):
        file = range(30)
        numberOfLinesInFile = len(file)
        progressWasCancelled = False
        progress = QtGui.QProgressDialog(
            "Parsing Log", "Stop", 0, numberOfLinesInFile, self)
        progress.setWindowModality(QtCore.Qt.WindowModal)
        progress.setMinimumDuration(0)
        for lineNumber, line in enumerate(file):
            progress.setValue(lineNumber)
            if progress.wasCanceled():
                progressWasCancelled = True
                break
            time.sleep(0.05)
        progress.setValue(numberOfLinesInFile)
        print 'cancelled', progress.wasCanceled(), progressWasCancelled
        progress.deleteLater()
if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    window = Window()
    window.show()
    sys.exit(app.exec_())
Run Code Online (Sandbox Code Playgroud)