如果用户拒绝配置对话框,请关闭 pyqt5 应用程序

Close pyqt5 app if user rejects the configuration dialog

我正在尝试创建一个与 Yandex Disk API(云存储)交互的应用程序,但设置失败 window。

这是设置对话框:

class SettingsUI(QDialog, Ui_Dialog):
    def __init__(self):
        super().__init__()
        self.setupUi(self)

        self.settings = QSettings('settings.ini', QSettings.IniFormat)

        self.toolButton.clicked.connect(lambda:self.lineEdit_watcher_folder.setText(QFileDialog.getExistingDirectory()))

    def isFirstRun(self):
        return True if self.settings.value('first_run') is None else False

    def getAPIKey(self):
        return self.settings.value('api_key')

    def getFolder(self):
        return self.settings.value('folder')

    def getWhitelistExtensions(self):
        return self.settings.value('files_extension')

    def getMailError(self):
        return self.settings.value('mail_error')

    def accept(self):
        if not self.lineEdit_API.text():
            QMessageBox.critical(self, 'Ошибка', 'Укажите API ключ для доступа к Yandex API')
        elif not self.lineEdit_watcher_folder.text() or not os.path.isdir(self.lineEdit_watcher_folder.text()):
            QMessageBox.critical(self, 'Ошибка', 'Укажите папку с файлами для загрузки')
        elif not self.lineEdit_allowed_ext.text():
            QMessageBox.critical(self, 'Ошибка', 'Не указаны форматы файлов')
        else:
            self.settings.setValue('first_run', False)
            self.settings.setValue('api_key', self.lineEdit_API.text())
            self.settings.setValue('folder', self.lineEdit_watcher_folder.text())
            self.settings.setValue('files_extension', tuple(self.lineEdit_allowed_ext.text().split(';')))
            self.settings.setValue('mail_error', self.lineEdit_mail_error.text())

            super().accept()

主要代码如下:

class MainUI(QMainWindow, Ui_MainWindow):
    def __init__(self):
        super().__init__()
        self.setupUi(self)

        self.setupTopMenu()
        self.firstRun()
        self.show()

    def setupTopMenu(self):
        self.settingsDialog = SettingsUI()
        self.settings_menu.triggered.connect(self.settingsDialog.exec)
        self.quit_menu.triggered.connect(self.shutdown)

    def shutdown(self):  # TODO method for correctly shutdown threads
        # sys.exit()
        qApp.quit()  

    def firstRun(self):
        if self.settingsDialog.isFirstRun():
            if self.settingsDialog.exec() == QDialog.Rejected:
                self.shutdown()


class WorkerNewTask(QObject):...


class WorkerYandexArchive(QObject):...


if __name__ == '__main__':
    app = QApplication(sys.argv)
    main_ui = MainUI()
    # main_ui.show()
    sys.exit(app.exec())

如果用户在第一个 运行 中取消设置 window 我想关闭应用程序,但是当解释器在关闭方法中达到 qApp.quit() 时,应用程序仍在运行.

同时如果我点击顶部菜单中的quit_menu按钮,它连接到关闭方法,它会关闭应用程序。

如果有人能告诉我我做错了什么,我会很高兴 :)。 亲切的问候,马克西姆

我认为原因是此时应用程序尚未完全初始化。注意调用链:MainUI() -> MainUI.__init__() -> MainUI.first_run() -> MainUI.settingsDialog.exec() -> MainUI.shutdown() -> qApp.quit()。但是,在脚本的 __name__ == '__main__' 部分,代码继续 app.exec()。所以可能是 app 在调用 quit() 时还没有初始化。

执行此操作的方法是关闭 window 并将应用程序设置为在最后一个 window 关闭时关闭

def shutdown(self):
    QApplication.instance().setQuitOnLastWindowClosed(True)
    self.close()