简体   繁体   中英

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.

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.

At the same time if I click on quit_menu button in top menu, which connected to shutdown method, it'll close app.

If someone can tell me what I did wrong I would be glad :). Kind regards, 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() . However, in __name__ == '__main__' part of the script the code continues with app.exec() . So it might be that app is simply not initialized yet when quit() is called.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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