私はここにあるpyqt5チュートリアルで働いています Zetcode、PyQt5
私自身の演習として、アプリを閉じるために使用された方法に関係なく、同じダイアログメッセージボックスが表示されるように例を拡張しようとしています。
ダイアログメッセージボックスはcloseEvent
メソッドで実装され、最後に完全なスクリプトが提供されます。
私は2つの問題を抱えています:
1。 [閉じる]ボタンをクリックすると、終了するのではなく、メッセージボックスダイアログを含むcloseEvent
メソッドを呼び出します。
「閉じる」プッシュボタンのサンプルコードの行を置き換えました。
btn.clicked.connect(QCoreApplication.instance().quit)
代わりに、必要なダイアログをすでに実装しているcloseEvent
メソッドを呼び出そうとしています。
btn.clicked.connect(self.closeEvent)
ただし、スクリプトを実行して[閉じる]ボタンをクリックし、ダイアログで結果の[閉じる]オプションを選択すると、次のようになります。
Traceback (most recent call last):
File "5-terminator.py", line 41, in closeEvent
event.accept()
AttributeError: 'bool' object has no attribute 'accept'
Aborted
誰かが私が間違っていることとここで何をする必要があるかをアドバイスできますか?
2。どういうわけかエスケープキーを押すと、メッセージボックスダイアログが表示され、正常に機能します。
わかりました、それが機能するのは素晴らしいことですが、CloseEvent
メソッドで定義されたメッセージボックス機能がkeyPressEvent
メソッド内で呼び出される方法と理由を知りたいです。
完全なスクリプトは次のとおりです。
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_())
誰かが私を啓発するために時間をかけることができることを願っています。
2番目の質問は最初の質問に答えます。
再実装されたkeyPressEvent
メソッドは close()
を呼び出し、ウィジェットにQCloseEvent
を送信します。続いて、ウィジェットの closeEvent
が、そのイベントを引数として呼び出されます。
したがって、ボタンをウィジェットのclose()
スロットに接続するだけで、すべてが期待どおりに機能します。
btn.clicked.connect(self.close)
X
ボタンとは異なり、カスタムボタンは_close event
_を渡すようには見えません。bool
だけです。そのため、この演習はX
ボタンでは機能しますが、通常のボタンでは機能しません。いずれにせよ、最初の質問では、次のように(pass
とaccept
の)代わりにdestroy()
とignore
を使用できます。
_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:
app.quit()
else:
pass
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_())
_
2番目の質問では、Qtはウィジェットに応じてデフォルトの動作をします(ダイアログには別の動作がある場合があります。メッセージダイアログが開いているときにEsc
キーを押してみてください)。 Esc
の動作をオーバーライドする必要がある場合は、次のことを試してください。
_def keyPressEvent(self, event):
if event.key() == QtCore.Qt.Key_Escape:
print("esc")
_
最終的に ZetCode でわかるように。