La barra de progreso de PyQt no se actualiza o aparece hasta el 100%

EDITAR: hay una cantidad de publicaciones similares en las barras de progreso de PyQt4 que no se actualizan. Todos se centran en el tema de los hilos y donde el progtwig actualiza la ventana. Aunque fue útil, mi código estaba tan estructurado que las respuestas no eran prácticas. La respuesta aceptada que se da aquí es simple, al punto y funciona.

Estoy usando Python 2.7 y PyQT 4 en una máquina Win 7 x64.

Estoy intentando borrar mi ventana de un widget, un botón ‘Aceptar’, ver el código y reemplazarlo con una barra de progreso.

Aunque cierro el botón “Aceptar” y añado la barra de progreso antes de ingresar al ciclo de procesamiento. La ventana solo se actualiza una vez que el bucle ha terminado y la barra de progreso salta directamente al 100%.

Mi código,

from PyQt4 import QtCore, QtGui import sys import time class CentralWidget(QtGui.QWidget): def __init__(self, parent=None): super(CentralWidget, self).__init__(parent) # set layouts self.layout = QtGui.QVBoxLayout(self) # Poly names self.pNames = QtGui.QLabel("Import file name", self) self.polyNameInput = QtGui.QLineEdit(self) # Polytype selection self.polyTypeName = QtGui.QLabel("Particle type", self) polyType = QtGui.QComboBox(self) polyType.addItem("") polyType.addItem("Random polyhedra") polyType.addItem("Spheres") polyType.addItem("Waterman polyhedra") polyType.activated[str].connect(self.onActivated) # Place widgets in layout self.layout.addWidget(self.pNames) self.layout.addWidget(self.polyNameInput) self.layout.addWidget(self.polyTypeName) self.layout.addWidget(polyType) self.layout.addStretch() # Combobox choice def onActivated(self, text): if text=="Random polyhedra": self.randomPolyhedra(text) if text=="Spheres": # not implementaed yet self.polyTypeName.setText("Not implemented yet.") self.polyTypeName.adjustSize() if text=="Waterman polyhedra": # not implementaed yet self.polyTypeName.setText("Not implemented yet.") self.polyTypeName.adjustSize() # New options for random polyhedra choice def randomPolyhedra(self, text): self.polyNumberLbl = QtGui.QLabel("How many: ", self) self.polyNumber = QtGui.QLineEdit(self) self.acceptSeed = QtGui.QPushButton('Accept') # Accept button created self.acceptSeed.clicked.connect(lambda: self.ranPolyGen()) self.layout.addWidget(self.polyNumberLbl) self.layout.addWidget(self.polyNumber) self.layout.addWidget(self.acceptSeed) # Accept button in layout self.randFlag = True self.polyTypeName.setText(text) self.polyTypeName.adjustSize() # Act on option choices for random polyhedra def ranPolyGen(self): polyCount = int(self.polyNumber.text()) self.progressBar = QtGui.QProgressBar() # Progress bar created self.progressBar.setMinimum(1) self.progressBar.setMaximum(polyCount) self.acceptSeed.close() # Accept button closed self.layout.addWidget(self.progressBar) # Add progressbar to layout for poly in range(1, polyCount+1): time.sleep(1) # Calls to main polyhedral generating code go here print poly self.progressBar.setValue(poly) self.doneLbl = QtGui.QLabel("Done", self) self.layout.addWidget(self.doneLbl) # Creates GUI class Polyhedra(QtGui.QMainWindow): def __init__(self): super(Polyhedra, self).__init__() # Place central widget in layout self.central_widget = CentralWidget(self) self.setCentralWidget(self.central_widget) # Set up window self.setGeometry(500, 500, 300, 300) self.setWindowTitle('Pyticle') self.show() # Combo box def onActivated(self, text): self.central_widget.onActivated(text) def main(): app = QtGui.QApplication(sys.argv) poly = Polyhedra() sys.exit(app.exec_()) if __name__ == '__main__': main() 

A continuación se muestra una imagen de durante la ejecución del bucle y después de su finalización.

No creo que tenga mi cabeza alrededor del método addWidget (). Tenía la impresión de que esto agregaría otro widget al diseño actual (un diseño de vbox aquí) y que el método .close () eliminaba un widget cuando se le indicaba que lo hiciera.

¿Qué me estoy perdiendo?

Durante la ejecución del bucle y después.

Puedes añadir:

 from PyQt4.QtGui import QApplication 

Entonces en tu bucle for:

 QApplication.processEvents() 

Su aplicación realmente deja de responder, debe llamar a processEvents() para procesar los eventos y volver a dibujar la interfaz gráfica de usuario. No estoy demasiado familiarizado con pyqt pero imagino que otra alternativa es usar un hilo.