退出应用程序时获取closeEvent

问题描述 投票:0回答:2

我正在尝试制作一个小型的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_closeon_exit

    def on_exit(self):
        for w in opened_windows.copy():
            w.on_close()
        if len(opened_windows) == 0:
            qApp.exit(1)

但是我想知道是否丢失了一种更好的方法,该方法不会强迫我维护一组打开的窗口。

python qt pyqt qt5
2个回答
0
投票

原因

重要的是要理解,应用程序和主窗口是相关的,但不是同一件事。因此,当您要关闭程序时,不必费心关闭应用程序。而是关闭主窗口。从QCloseEvent 的文档中:

Close事件被发送到用户想要关闭的窗口小部件,通常是通过从窗口菜单中选择“关闭”,或者通过单击X标题栏按钮。当您调用QWidget :: close()以编程方式关闭小部件时,也会发送它们。

解决方案

将退出动作的triggered信号连接到closeMainWindow插槽。您的情况,而不是:

self.create_action(self.on_exit, _file_menu, '&Exit')

write:

self.create_action(self.close, _file_menu, '&Exit').

0
投票

有一种建议将修改的数据保存在信号quitexit上的方法。>

请注意,尽管QCoreApplication::aboutToQuit表示无法进行用户交互,但至少使用PyQt5,我可以使用QMessageBox而不会出现明显的问题。

© www.soinside.com 2019 - 2024. All rights reserved.