2017-06-29 4 views
1

In Windows 10, wenn ich die folgenden Testfall GUI-Anwendung von der Befehlszeile ('Python ./pyqt_freeze_testcase.py') ausführen, sehe ich die folgende vollständig wiederholbare GUI einfrieren/hängen/nicht reagieren Verhalten; Jedes Mal, wenn die GUI nicht mehr reagiert, kann ich sie "wieder zum Leben erwecken", indem ich einen beliebigen Schlüssel in der Shell eintippe.pyqt5 Klick im Terminal verursacht GUI Freeze

UPDATE: Dies scheint ausgelöst werden (und geheilt) durch Umschalten der Fokus-folgt-Maus-ohne-Raise-the-Window-Verhalten; Jetzt stellt sich die Frage, wie man das Einfrieren verhindern kann, wenn Fokus-folgt-Maus-ohne-Erhöhung aktiviert ist. Ich habe eine neue Frage zu diesem Thema geschrieben: PyQt5 GUI freeze caused by Windows focus-follows-mouse

Das Verhalten ist das gleiche für die integrierte Shell ('cmd') und für PowerShell. Ein detailliertes Skript mit Aktionen und Antworten zur Veranschaulichung des Einfrierens finden Sie am Ende dieses Posts. Wie kann ich das Einfrieren verhindern/sicherstellen, dass die GUI-Anwendung reaktionsfähig bleibt?

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() 

Die GUI ist nur ein Dialog mit einer LineEdit und einer Taste (mit Signal/Schlitz).

UI-Datei minimal_ui.py Begleit (von Qt Designer und 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")) 

Die detaillierten Aktionen und Reaktionen, von einer neuen Powershell beginnen:

  1. Python ./pyqt_freeze_testcase.py
  2. Verschieben Sie das GUI-Fenster so, dass es sich neben der PowerShell (nicht innerhalb der) befindet; Argumentation ist offensichtlich unter
  3. die LineEdit klicken und ein paar Sachen geben Sie links -> das Material in der LineEdit zeigt sich, wie erwartet
  4. den Taster klicken links - ‚Wirklich?‘> die QMessageBox erscheint
  5. die linke Maustaste irgendwo in der Powershell -> die Powershell angehoben wird, die die GUI-Anwendung verdecken würde, was der Grund für den Schritt 2 oben
  6. klicken links entweder ‚Ja‘ oder ‚Nein‘ - -> Die Meldungsbox wird geschlossen, aber es wird keine Ausgabe in der Shell angezeigt, und die GUI reagiert nicht (sie erhält bald den Spinner/die Sanduhr, das Banner sagt "Dialog (Reagiert nicht)") und Sie können das Lineedit nicht auswählen geben Sie mehr Material, und klicken Sie auf die Drucktaste tut nichts, denn allem Anschein nach wird die GUI eingefroren, aber:
  7. links~~POS=TRUNC überall in der Powershell
  8. eine beliebige Taste drücken - > die erwartete Antwort (yep oder nope) erscheint in der Shell und die GUI reagiert jetzt wieder, d. h. Sie können das alles ab Schritt 3 wiederholen; auch beachten, dass jede zusätzliche Eingabe Sie nun während des Gefrier getan haben, können in der LineEdit

Antwort

0

Dies ist wahrscheinlich besser als Kommentar erscheinen, aber ich nicht die Rating-Punkte haben, dies zu tun und einige Feedback ist wahrscheinlich besser für dich als keiner.

Ich habe genau getestet, was Sie auf meinem Windows 10-Rechner mit python3 und python2.7 gemacht haben, und ich kann die Situation, die Sie in Ihrer Frage umrissen haben, nicht replizieren. Alles funktioniert wie erwartet und die "Nö" - und "Yep" -Meldungen erscheinen sofort.Sie können versuchen, etwas wie dieses: PySide/Python GUI freezes, aber eine print-Anweisung sollte nicht Ihre GUI einfrieren und nicht in der Konsole drucken. Sie sollten auf jeden Fall ein paar andere einfache GUIs wie Ihre überprüfen, um zu sehen, was friert und was nicht. Ich würde Ihren Computer jedoch zuerst neu starten. Wenn das nicht zu Antworten führt, versuchen Sie vielleicht, PyQt5 erneut zu installieren.

+0

das half mir tatsächlich eine direktere Ursache zu finden. Ich habe vergessen, dass ich X-Maus im Spiel hatte, um Linux Fokus-folgt-Maus-ohne-Raise-the-window-Verhalten nachzuahmen (dort ein paar verschiedene Dinge, die X-Mouse genannt werden - das ist das von https: // joelpurra .com/projekte/X-Mouse_Controls /). Wenn das ausgeschaltet wird, wird das behoben, d. H. Das Einfrierverhalten verschwindet und ein Klicken in das Terminal ändert nichts. Also habe ich versucht, die ähnlichen Registry-Mods von https://sinewalker.wordpress.com/2010/03/10/ms-windows-focus-follows-mouse-registry-hacks/ - sie funktionieren immer noch auf Windows 10 - und das löst aus es! –

+0

(Fortsetzung Kommentar) - also X-Mouse macht wahrscheinlich nur die gleichen Regedit-Zeilen. Ohne sie gibt es kein Einfrieren; mit ihnen; Ich bekomme das oben beschriebene Freeze-Verhalten. –

+0

Also, es wäre toll, wenn jemand versuchen könnte, dies zu reproduzieren! Unabhängig davon werde ich eine neue Frage eröffnen, da sich der Umfang ziemlich verändert hat. Vielen Dank! –

0

Die Brute-Force-Lösung arbeitet in der Frage nach oben verknüpft (PyQt5 GUI freeze caused by Windows focus-follows-mouse); Der vollständige Code wird dort veröffentlicht.

Hoffentlich kann jemand eine optimale oder mehr "richtige" Lösung bieten?

Deaktivieren Sie die aktive Fensterverfolgung in MainWindow init und stellen Sie die ursprüngliche Einstellung in MainWindow closeEvent wieder her. Vielleicht gibt es eine bessere Lösung, aber diese ist kurz und zuverlässig. Die Methode von https://joelpurra.com/projects/X-Mouse_Controls/ wird sofort wirksam, während der Registry-Hack erst beim Neustart wirksam wird.

Verwandte Themen