我正在通过这里找到的pyqt5教程Zetcode, PyQt5
工作作为我自己的练习,我试图扩展一个示例,以便向我显示相同的对话框消息框,无论用于关闭应用程序的方法如何:
对话框消息框以closeEvent
方法实现,最后提供完整脚本。
我有两个问题:
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_())
希望有人能抽出时间来启发我。
答案 0 :(得分:6)
你的第二个问题回答了第一个问题。
重新实现的keyPressEvent
方法调用close()
,它会向窗口小部件发送QCloseEvent
。随后,将使用该事件作为其参数调用窗口小部件closeEvent
。
所以你只需要将按钮连接到小工具的close()
插槽,一切都会按预期工作:
btn.clicked.connect(self.close)
答案 1 :(得分:0)
与X
按钮不同,您的自定义按钮似乎只传递close event
bool
。这就是为什么这个练习应该适用于X
按钮但不适用于普通按钮的原因。在任何情况下,对于您的第一个问题,您可以使用destroy()
和pass
代替(accept
和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_())
对于您的第二个问题,Qt具有默认行为,具体取决于Widget(对话框可能有另一个,当您的消息对话框打开时,请尝试按Esc
键查看)。当您确实需要覆盖Esc
行为时,您可以尝试这样做:
def keyPressEvent(self, event):
if event.key() == QtCore.Qt.Key_Escape:
print("esc")
正如您最终会在ZetCode中看到的那样。