pyqt5 - fermeture/fin de l'application
Je travaille bien le pyqt5 tutoriel trouvé ici Zetcode, PyQt5
Comme un exercice pour moi, je suis en train de développer un exemple, alors que je suis présenté avec la même boîte de dialogue boîte de message, indépendamment de la méthode utilisée pour fermer l'application:
- cliquant sur le bouton " X " dans la barre de titre (fonctionne comme prévu)
- cliquant sur le bouton "Fermer" (produit de l'attribut d'erreur)
- de la touche 'echap' clé (travaux mais vous ne savez pas comment/pourquoi)
La boîte de dialogue boîte de message est mis en œuvre dans le closeEvent
méthode, plein de script fourni à la fin.
J'ai deux questions:
1. Lorsque vous cliquez sur le bouton "Fermer", au lieu de simplement arrêter de fumer, je tiens à appeler closeEvent
méthode, y compris la boîte de dialogue de message.
J'ai remplacé une ligne de l'exemple de code pour le "Fermer" bouton-poussoir:
btn.clicked.connect(QCoreApplication.instance().quit)
Et au lieu essaye d'appeler le closeEvent
méthode qui implémente déjà la boîte de dialogue je veux:
btn.clicked.connect(self.closeEvent)
Cependant lorsque je lance le script et cliquez sur le bouton "Fermer" et sélectionnez la résultante de "Fermer" option dans la boîte de dialogue je reçois le texte suivant:
Traceback (most recent call last):
File "5-terminator.py", line 41, in closeEvent
event.accept()
AttributeError: 'bool' object has no attribute 'accept'
Aborted
Quelqu'un peut conseiller ce que je fais mal et ce qui doit être fait ici?
2. Lors de la frappe de la touche d'échappement en quelque sorte le message de la boîte de dialogue est présentée et fonctionne très bien.
Ok, c'est génial que cela fonctionne, mais je voudrais savoir comment et pourquoi le message de la boîte de fonctionnalités définies dans CloseEvent
méthode est appelée dans la keyPressEvent
méthode.
Plein de script suit:
import sys
from PyQt5.QtWidgets import (
QApplication, QWidget, QToolTip, QPushButton, QMessageBox)
from PyQt5.QtCore import QCoreApplication, Qt
class Window(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
btn = QPushButton("Close", self)
btn.setToolTip("Close Application")
# btn.clicked.connect(QCoreApplication.instance().quit)
# instead of above button signal, try to call closeEvent method below
btn.clicked.connect(self.closeEvent)
btn.resize(btn.sizeHint())
btn.move(410, 118)
self.setGeometry(30, 450, 500, 150)
self.setWindowTitle("Terminator")
self.show()
def closeEvent(self, event):
"""Generate 'question' dialog on clicking 'X' button in title bar.
Reimplement the closeEvent() event handler to include a 'Question'
dialog with options on how to proceed - Save, Close, Cancel buttons
"""
reply = QMessageBox.question(
self, "Message",
"Are you sure you want to quit? Any unsaved work will be lost.",
QMessageBox.Save | QMessageBox.Close | QMessageBox.Cancel,
QMessageBox.Save)
if reply == QMessageBox.Close:
event.accept()
else:
event.ignore()
def keyPressEvent(self, event):
"""Close application from escape key.
results in QMessageBox dialog from closeEvent, good but how/why?
"""
if event.key() == Qt.Key_Escape:
self.close()
if __name__ == '__main__':
app = QApplication(sys.argv)
w = Window()
sys.exit(app.exec_())
Espère que quelqu'un peut prendre le temps de m'éclairer.
Vous devez vous connecter pour publier un commentaire.
Votre deuxième question, les réponses à la première question.
La réimplémentée
keyPressEvent
les appels de méthodeclose()
, qui envoie unQCloseEvent
pour le widget. Par la suite, le widget estcloseEvent
sera appelé à cet événement en tant que son argument.Donc, vous avez juste besoin de connecter le bouton pour le widget de l'
close()
fente, et tout fonctionnera comme prévu:QMessageBox.Save | QMessageBox.Close | QMessageBox.Cancel
. Je suis en supposant qu'il définit automatiquement dans l'ordre alphabétique croissant?Contrairement à la
X
bouton de votre bouton personnalisé ne semble pas passer unclose event
juste unbool
. C'est pourquoi cet exercice devrait fonctionner pour laX
le bouton, mais pas d'un bouton normal. En tout cas, pour votre première question, vous pouvez utiliserdestroy()
etpass
à la place (deaccept
etignore
) comme cela:Pour votre deuxième question Qt a des comportements par défaut en fonction du Widget (boîtes de dialogue peuvent avoir une autre, essayez d'appuyer sur le
Esc
clé lors de votre boîte de Dialogue de Message est ouvert juste pour voir). Quand vous en avez besoin pour remplacer laEsc
comportement que vous pourriez essayer ceci:Que vous finirez par voir dans ZetCode.
destroy()
va supprimer le widget et quitter l'application en cours d'exécution avec aucun moyen de l'arrêter, ce qui n'est certainement pas la bonne chose à faire. Aussi, comme l'OP a déjà dit, l'keyPressEvent
fonctionne, donc il n'est pas nécessaire de le changer.