2016-05-04 8 views
0

PyQt4/5 auf OSX El CapitanQDialog hält blockiert Mauseingabe auch nach dem Schließen

Ich habe eine QMessageBox/QDialog die ich modal sein wollen und eine Eingabe von anderen GUI-Elemente blockieren, während ein Prozess ausgeführt wird. Der QDialog sollte dem Benutzer die Möglichkeit bieten, den besagten Prozess abzubrechen, ihm aber in der Zwischenzeit nicht erlauben, etwas anderes mit der GUI zu tun.

Sobald der Prozess beendet ist, sollte er den QDialog schließen und die Eingabe für die Hauptanwendung wieder aktivieren. Da während der Anzeige des Dialogs Dinge im Hintergrund passieren sollten, verwende ich exec_() nicht, um den Dialog anzuzeigen.

Hier ist ein einfaches Beispiel meines Code:

self.openingDialog = QtWidgets.QMessageBox(self.main_window) 
self.openingDialog.setText(_(u"Opening experiment. Please wait")) 
self.openingDialog.setStandardButtons(QtWidgets.QMessageBox.Cancel) 
self.openingDialog.reject.connect(<some_function>) 
self.openingDialog.show() 
self.openingDialog.raise_() 

... [Perform process] ... 

self.openingDialog.done(0) 
self.openingDialog.close() 
self.openingDialog.deleteLater() 

Alles funktioniert gut in dem Sinne, dass das Dialogfeld angezeigt wird, und dass keine Interaktion möglich ist, mit anderen GUI-Elementen, während es angezeigt wird. Wenn der Vorgang jedoch abgeschlossen ist, wird das Dialogfeld automatisch geschlossen, es ist jedoch nachher nicht möglich, mit anderen GUI-Elementen zu interagieren. Die GUI reagiert nicht auf Mausklicks, auf Menüelemente kann nicht zugegriffen werden, und Sie können nicht einmal auf die Schließen-Schaltfläche klicken, sodass die Anwendung Force Quit sein muss.

Was mache ich falsch beim automatischen Schließen des QDialogs?

+0

Funktioniert die Abbrechen-Schaltfläche des Dialogfelds wie erwartet? Was passiert, wenn Sie die letzten vier Zeilen loswerden und stattdessen den Dialog ausblenden()? Haben Sie auch bestätigt, dass nur der Dialog das Problem verursacht? – ekhumoro

+0

Ja, wenn ich cancel drücke, erhält man die Kontrolle über die Schnittstelle zurück. Und wenn ich den Dialog komplett verlasse, funktioniert die App wie gewünscht. hide() hat den gleichen Effekt wie close(), da das Steuerelement nicht die GUI zurückgibt. –

+0

Okay, also versuch die letzten vier Zeilen durch 'reject()' zu ersetzen. – ekhumoro

Antwort

0

Ok, ich habe eine Art Workaround gefunden, obwohl ich nicht denke, dass es eine elegante Lösung ist.

Wenn ich die Fenster Modalität ‚Fenster modal‘ anstelle von ‚Anwendung modal‘ unter Verwendung:

self.openingDialog.setWindowModality(QtCore.Qt.WindowModal) 

dann gewinnt die Anwendung konzentrieren und Zugänglichkeit nach dem Dialog wird durch das Programm geschlossen. Immer noch löst dies nicht das Problem, wenn der Dialog eine Anwendung modal ist, aber das dient jetzt meine Bedürfnisse.

+0

Jetzt * das ist * interessant. Klügere Leute als ich können dies als einen Randfall betrachten, der einen Fehlerbericht benötigt. –

+0

Das habe ich mir gedacht! Ich halte mich selbst nicht weise genug, um wirklich zu sagen, dass dies ein Fehler ist, aber es scheint sicherlich wie unbeabsichtigtes Verhalten. –