pyqt5 - closing/terminating 应用程序
pyqt5 - closing/terminating application
我正在学习这里的 pyqt5 教程 Zetcode, PyQt5
作为我自己的练习,我尝试扩展一个示例,以便无论使用何种方法关闭应用程序,我都会看到相同的对话框:
- 单击标题栏中的 'X' 按钮(按预期工作)
- 单击 'Close' 按钮(产生属性错误)
- 按 'escape' 键(有效但不确定 how/why)
消息框在closeEvent
方法中实现,完整脚本在文末提供。
我有两个问题:
1.单击 'Close' 按钮时,我想调用 closeEvent
方法,包括消息框对话框。
我已经为 'Close' 按钮替换了一行示例代码:
btn.clicked.connect(QCoreApplication.instance().quit)
而是尝试调用 closeEvent
方法,该方法已经实现了我想要的对话框:
btn.clicked.connect(self.closeEvent)
然而,当我 运行 脚本并单击 'Close' 按钮和 select 对话框中生成的 'Close' 选项时,我得到以下信息:
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_())
希望有人能抽空赐教
你的第二个问题回答了第一个问题。
重新实现的 keyPressEvent
方法调用 close()
, which sends a QCloseEvent
to the widget. Subsequently, the widget's closeEvent
将以该事件作为参数调用。
所以您只需要将按钮连接到小部件的 close()
插槽,一切都会按预期工作:
btn.clicked.connect(self.close)
与 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 中看到的那样。
closeEvent()
在右上方的勾号代码中,请检查 closeEvent 它是相同的,否则浪费时间研究。
我正在学习这里的 pyqt5 教程 Zetcode, PyQt5
作为我自己的练习,我尝试扩展一个示例,以便无论使用何种方法关闭应用程序,我都会看到相同的对话框:
- 单击标题栏中的 'X' 按钮(按预期工作)
- 单击 'Close' 按钮(产生属性错误)
- 按 'escape' 键(有效但不确定 how/why)
消息框在closeEvent
方法中实现,完整脚本在文末提供。
我有两个问题:
1.单击 'Close' 按钮时,我想调用 closeEvent
方法,包括消息框对话框。
我已经为 'Close' 按钮替换了一行示例代码:
btn.clicked.connect(QCoreApplication.instance().quit)
而是尝试调用 closeEvent
方法,该方法已经实现了我想要的对话框:
btn.clicked.connect(self.closeEvent)
然而,当我 运行 脚本并单击 'Close' 按钮和 select 对话框中生成的 'Close' 选项时,我得到以下信息:
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_())
希望有人能抽空赐教
你的第二个问题回答了第一个问题。
重新实现的 keyPressEvent
方法调用 close()
, which sends a QCloseEvent
to the widget. Subsequently, the widget's closeEvent
将以该事件作为参数调用。
所以您只需要将按钮连接到小部件的 close()
插槽,一切都会按预期工作:
btn.clicked.connect(self.close)
与 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 中看到的那样。
closeEvent()
在右上方的勾号代码中,请检查 closeEvent 它是相同的,否则浪费时间研究。