我正在尝试制作一个小型的python程序,该程序可以具有多个窗口。问题是,当我尝试实现菜单项以退出程序时,立即关闭所有窗口。我尝试使用qApp.close()
和qApp.exit()
,但如果允许有效退出程序,则不会为仍打开的窗口生成关闭事件,这会阻止我保存修改后的数据或防止离开应用程序。最佳做法是什么?我能理解无法取消退出过程,但是我真正想要的是能够建议保存修改后的数据。
import sys
from PyQt5.QtWidgets import *
opened_windows = set()
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.create_actions()
opened_windows.add(self)
def closeEvent(self, ev):
if QMessageBox.question(self, 'Closing', 'Really close?') == QMessageBox.Yes:
ev.accept()
opened_windows.remove(self)
else:
ev.ignore()
def create_action(self, action_callback, menu, action_name):
action = QAction(action_name, self)
action.triggered.connect(action_callback)
menu.addAction(action)
def create_actions(self):
_file_menu = self.menuBar().addMenu('&File')
self.create_action(self.on_new, _file_menu, '&New')
_file_menu.addSeparator()
self.create_action(self.on_close, _file_menu, '&Close')
self.create_action(self.on_quit, _file_menu, '&Quit')
self.create_action(self.on_exit, _file_menu, '&Exit')
def on_new(self):
win = MainWindow()
win.show()
def on_close(self):
self.close()
def on_quit(self):
qApp.quit()
def on_exit(self):
qApp.exit(1)
if __name__ == '__main__':
app = QApplication(sys.argv)
win = MainWindow()
win.show()
status = app.exec()
print(len(opened_windows), ' window(s) opened')
print('status = ', status)
sys.exit(status)
当前,我正在像这样修改on_close
和on_exit
:
def on_exit(self):
for w in opened_windows.copy():
w.on_close()
if len(opened_windows) == 0:
qApp.exit(1)
但是我想知道是否丢失了一种更好的方法,该方法不会强迫我维护一组打开的窗口。
重要的是要理解,应用程序和主窗口是相关的,但不是同一件事。因此,当您要关闭程序时,不必费心关闭应用程序。而是关闭主窗口。从QCloseEvent 的文档中:
Close事件被发送到用户想要关闭的窗口小部件,通常是通过从窗口菜单中选择“关闭”,或者通过单击X标题栏按钮。当您调用QWidget :: close()以编程方式关闭小部件时,也会发送它们。
将退出动作的triggered
信号连接到close
的MainWindow
插槽。您的情况,而不是:
self.create_action(self.on_exit, _file_menu, '&Exit')
write:
self.create_action(self.close, _file_menu, '&Exit').
有一种建议将修改的数据保存在信号quit
和exit
上的方法。>
请注意,尽管QCoreApplication::aboutToQuit
表示无法进行用户交互,但至少使用PyQt5,我可以使用QMessageBox而不会出现明显的问题。