简体   繁体   English

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

[英]Close pyqt5 app if user rejects the configuration dialog

I'm trying to create an app to interact with Yandex Disk API (Cloud storage) but have been failed with settings window. 我正在尝试创建一个与Yandex Disk API(云存储)交互的应用程序,但在设置窗口中失败了。

Here is settings dialog: 这是设置对话框:

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()

Here is the main code: 这是主要代码:

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())

I would like to close app if user cancels the settings window in the first run but when interpreter is reaches qApp.quit() in shutdown method, the app is still working. 如果用户在第一次运行时取消了设置窗口,但是我想关闭应用程序,但是当解释器在关闭方法中到达qApp.quit()时,该应用程序仍在工作。

At the same time if I click on quit_menu button in top menu, which connected to shutdown method, it'll close app. 同时,如果我单击顶部菜单中的quit_menu按钮,该按钮已连接到关机方法,它将关闭应用程序。

If someone can tell me what I did wrong I would be glad :). 如果有人可以告诉我我做错了什么,我会很高兴的:)。 Kind regards, Maxim 亲切的问候,Maxim

I think the reason is that application is not completely initialized at that point. 我认为原因是此时应用程序尚未完全初始化。 Note the calls chain: MainUI() -> MainUI.__init__() -> MainUI.first_run() -> MainUI.settingsDialog.exec() -> MainUI.shutdown() -> qApp.quit() . 请注意调用链: MainUI() -> MainUI.__init__() -> MainUI.first_run() -> MainUI.settingsDialog.exec() -> MainUI.shutdown() -> qApp.quit() However, in __name__ == '__main__' part of the script the code continues with app.exec() . 但是,在脚本的__name__ == '__main__'部分中,代码以app.exec()继续。 So it might be that app is simply not initialized yet when quit() is called. 因此,可能是在调用quit()时尚未完全初始化app

The way to do this would be to just close the window and set the application to close when the last window closes 这样做的方法是只关闭窗口,并在最后一个窗口关闭时将应用程序设置为关闭

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM