I am using a progress dialog with a "pulse" progress bar to show that the app is busy calculating. I want to show a filled bar as soon as it finishes (the finished signal is received) to indicate that the process is complete. I've tried all the options given in similar questions (change value, set min/max, range, processEvents, etc), but the progress bar remains empty when the process is complete.
Below is a simple working example. You can change the end number in the run subroutine if it takes too little or too much time in your machine.
from PyQt4 import QtCore, QtGui
import sys
class TestDialog(QtGui.QDialog):
def __init__(self,parent=None):
super(TestDialog,self).__init__()
self.resize(50, 50)
self.Button = QtGui.QPushButton(self)
self.Button.clicked.connect(self.Run_Something)
self.Button.setText("Run")
def Run_Something(self):
self.progress = QtGui.QProgressDialog("Running","Cancel",0,0,self)
self.progress.setWindowTitle('Please wait...')
self.progress.setWindowModality(QtCore.Qt.WindowModal)
self.progress.canceled.connect(self.progress.close)
self.progress.show()
self.TT = Test_Thread()
self.TT.finished.connect(self.TT_Finished)
self.progress.canceled.connect(self.progress.close)
self.progress.show()
self.TT.start()
def TT_Finished(self):
self.progress.setLabelText("Analysis finished")
self.progress.setRange(0,1)
self.progress.setValue(1)
self.progress.setCancelButtonText("Close")
self.progress.canceled.connect(self.progress.close)
class Test_Thread(QtCore.QThread):
finished = QtCore.pyqtSignal()
def __init__(self):
QtCore.QThread.__init__(self)
def run(self):
end = 10**7
start = 0
while start < end:
start += 1
self.finished.emit()
self.terminate()
if __name__=='__main__':
app = QtGui.QApplication(sys.argv)
Test = TestDialog()
Test.show()
sys.exit(app.exec_())
Any help is appreciated. Thanks!
Firstly, Happy 5000th tagged "pyqt" question :P
On to your problem. I have no idea why it is doing this, but here is a "work around".
If you set the value of the QProgressDialog
to it's maximum value before showing it (despite the fact that the max value is set to 0 at this stage) then your code works.
E.g.
self.progress.setValue(1)
self.progress.show()
In a bizarre twist, if you don't use the above "fix" but instead set the range to be between 0 and 2, then your code does successfully set it to 50% at the end of the thread. However, trying to set it to 100% (setValue(2)
) results in the same faulty behaviour you observed.
So, hopefully that helps you move on. It still baffles me as to why it's happening at all though. I think it might be a bug.