tutorial español pyqt freeze

español - El clic de pyqt5 en la terminal causa la congelación de la GUI



qt designer pyqt5 (2)

En Windows 10, si ejecuto la siguiente aplicación GUI de caso de prueba desde la línea de comando (''python ./pyqt_freeze_testcase.py''), veo el siguiente comportamiento completamente repetible de congelación / cuelgue / no responde; cada vez que la GUI deja de responder, puedo "devolverle la vida" escribiendo cualquier clave en el intérprete de comandos.

ACTUALIZACIÓN: parece que se desencadena (y cura) al alternar el comportamiento de enfoque-sigue-ratón-sin-levantar-la-ventana; ahora la pregunta es cómo evitar las congelaciones cuando el enfoque sigue al ratón sin levantar está habilitado. Publiqué una nueva pregunta para ese tema: la congelación de la GUI de PyQt5 causada por el mouse de enfoque de Windows sigue

El comportamiento es el mismo para el shell incorporado (''cmd'') y para PowerShell. La secuencia de comandos detallada de acciones y respuestas para ilustrar la congelación se encuentra en la parte inferior de esta publicación. ¿Cómo puedo evitar la congelación / asegurarme de que la aplicación GUI se mantenga receptiva?

pyqt_freeze_testcase.py:

from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * import sys # import the UI file created with pyuic5 from minimal_ui import Ui_Dialog class MyWindow(QDialog,Ui_Dialog): def __init__(self,parent): QDialog.__init__(self) self.parent=parent self.ui=Ui_Dialog() self.ui.setupUi(self) def showMsg(self): self.really1=QMessageBox(QMessageBox.Warning,"Really?","Really do stuff?", QMessageBox.Yes|QMessageBox.No,self,Qt.WindowTitleHint|Qt.WindowCloseButtonHint|Qt.Dialog|Qt.MSWindowsFixedSizeDialogHint|Qt.WindowStaysOnTopHint) self.really1.show() self.really1.raise_() if self.really1.exec_()==QMessageBox.No: print("nope") return print("yep") def main(): app = QApplication(sys.argv) w = MyWindow(app) w.show() sys.exit(app.exec_()) if __name__ == "__main__": main()

La GUI es solo un diálogo con un lineedit y un botón (con señal / ranura).

Archivo de IU de acompañamiento minimal_ui.py (de Qt Designer y pyuic5):

# -*- coding: utf-8 -*- # Form implementation generated from reading ui file ''minimal.ui'' # # Created by: PyQt5 UI code generator 5.8.2 # # WARNING! All changes made in this file will be lost! from PyQt5 import QtCore, QtGui, QtWidgets class Ui_Dialog(object): def setupUi(self, Dialog): Dialog.setObjectName("Dialog") Dialog.resize(400, 300) self.lineEdit = QtWidgets.QLineEdit(Dialog) self.lineEdit.setGeometry(QtCore.QRect(120, 90, 113, 22)) self.lineEdit.setObjectName("lineEdit") self.pushButton = QtWidgets.QPushButton(Dialog) self.pushButton.setGeometry(QtCore.QRect(130, 150, 93, 28)) self.pushButton.setObjectName("pushButton") self.retranslateUi(Dialog) self.pushButton.clicked.connect(Dialog.showMsg) QtCore.QMetaObject.connectSlotsByName(Dialog) def retranslateUi(self, Dialog): _translate = QtCore.QCoreApplication.translate Dialog.setWindowTitle(_translate("Dialog", "Dialog")) self.pushButton.setText(_translate("Dialog", "PushButton"))

Las acciones y respuestas detalladas, a partir de un nuevo PowerShell:

  1. python ./pyqt_freeze_testcase.py
  2. mueva la ventana de la GUI para que esté al lado (no dentro) de PowerShell; el razonamiento es evidente a continuación
  3. Haga clic izquierdo en el lineedit y escriba algunas cosas -> dichas cosas aparecen en el lineedit, como se esperaba
  4. Haga clic izquierdo en el botón -> el ''¿En serio?'' QMessageBox aparece
  5. Haga clic con el botón izquierdo en cualquier lugar de PowerShell -> se inicia PowerShell, lo que oscurecería la aplicación de GUI, que es la razón para el paso 2 anterior
  6. Haga clic con el botón izquierdo en ''Sí'' o ''No'' -> el cuadro de mensaje se cierra, pero no se muestra ningún resultado en el shell y la GUI no responde (pronto recibe el giro / reloj de arena, el cartel dice ''Diálogo (no responde) ) ''y no puede seleccionar el lineedit para escribir más cosas, y al hacer clic en el botón no se hace nada; en todo caso, la GUI está congelada, pero:
  7. Haga clic izquierdo en cualquier lugar de PowerShell
  8. presione cualquier tecla -> la respuesta esperada (sí o no) aparece en el intérprete de órdenes, y la GUI ahora responde de nuevo, es decir, puede repetir todo esto comenzando en el paso 3; También tenga en cuenta que cualquier tipeo adicional que haya realizado durante la congelación aparecerá ahora en el lineedit.

Es probable que sea mejor como comentario, pero no tengo los puntos de reputación para hacerlo y algunos comentarios son probablemente mejores para usted que ninguno.

Probé exactamente lo que hizo en mi máquina con Windows 10 con python3 y python2.7 y no puedo replicar la situación que describió en su pregunta. Todo funciona como se espera y los mensajes "nope" y "sip" aparecen inmediatamente. Puede intentar algo como esto: PySide / Python GUI se congela, pero una declaración de impresión no debe congelar su GUI y no imprimir en la consola. Definitivamente deberías consultar algunas otras GUI simples como la tuya para ver qué se congela y qué no. Sin embargo, primero reiniciaré tu computadora. Si eso no lleva a ninguna respuesta, quizás intente reinstalar PyQt5.


La solución de fuerza bruta está trabajando en la pregunta vinculada a arriba ( congelación de la GUI PyQt5 causada por el enfoque de Windows sigue al mouse ); el código completo está publicado allí.

¿Esperemos que alguien pueda brindar una solución más óptima o más "correcta"?

Básicamente, deshabilite el seguimiento de ventanas activas en MainWindow init y restaure su configuración inicial en MainWindow closeEvent. Tal vez hay una solución más óptima, pero esta es corta y confiable. El método de https://joelpurra.com/projects/X-Mouse_Controls/ tiene efecto de inmediato, mientras que el registro no se aplica hasta que se reinicia.