¿Cómo hacer que el pulsador se desactive inmediatamente?

¡Hola a todos! He encontrado algo extraño en la instancia de QPushButton. Oh, en primer lugar, estoy usando ..

  • ventanas 7
  • python 3.4
  • PyQt5

Mi código de prueba es …

# coding: utf-8 import sys, time from PyQt5.QtWidgets import QWidget, QApplication, QPushButton class Example(QWidget): def __init__(self): super().__init__() self.initUI() def initUI(self): self.targetBtn = QPushButton('target', self) self.targetBtn.move(100, 100) self.targetBtn.clicked.connect(self.sleep5sec) self.setGeometry(100, 100, 300, 300) self.show() def sleep5sec(self): self.targetBtn.setEnabled(False) time.sleep(5) if __name__ == '__main__': app = QApplication(sys.argv) ex = Example() sys.exit(app.exec_()) 

Lo que quiero es … cuando un usuario presiona el botón de destino, el botón se desactiva inmediatamente. Pero en mi código, el botón de destino está deshabilitado después de dormir (5).

¿Qué pasa con mi código?

¡Gracias por leer mi pregunta! ¡Por favor ayuda!

Como se sugiere en el hilo que vinculé en el comentario y @MichalF, el sleep de python congela completamente la interfaz de usuario, por lo que no permite que el método .setEnabled se actualice.

En Qt, todos los eventos se gestionan con el subproceso principal de la interfaz de usuario (que es otro trabajador) y, por lo tanto, las acciones como .setEnabled no tienen un efecto inmediato en la interfaz de usuario (requiere un poco de repintado). Al usar time.sleep los time.sleep la IU se congelan y, por lo tanto, el trabajador principal de Qt no actualiza (repinta) la UI hasta que finaliza el temporizador.

Una forma de cambiarlo es mediante PyQt5.QtCore.QTimer:

 def sleep5sec(self): self.targetBtn.setEnabled(False) QTimer.singleShot(5000, lambda: self.targetBtn.setDisabled(False)) 

El ejemplo anterior deshabilitaría instantáneamente targetBtn y después de 5 segundos lo volverá a habilitar nuevamente.

Regla de oro: NO UTILICE sleep() EN LA APLICACIÓN GUI!

La aplicación de GUI de casi cualquier tipo funciona en algo llamado event loop , que es un mecanismo de un solo hilo que responde a los eventos pasados ​​desde el sistema operativo (o sistema Windows). Si duermes allí, tu bucle de eventos no funciona.

Cuando se conectó, clicked señal a un método que duerme en el interior, el bucle de eventos no tiene la oportunidad de finalizar el manejo de la señal y actualizar la imagen de la interfaz en la pantalla, como ocurre después de que se maneja la señal. Los elementos gráficos de actualización se realizan mediante una serie de señales enviadas internamente.