From c1a008dce1dc4376c40e5ac18eb137cac2ec1a2b Mon Sep 17 00:00:00 2001 From: loathingKernel <142770+loathingKernel@users.noreply.github.com> Date: Sun, 23 Oct 2022 16:06:54 +0300 Subject: [PATCH] MainWindow: Don't connect to the global exit signal Instead of connecting to the global `exit_app` signal, pass the signals through their respective widgets. Because signals are queued by default, this ensures that slots are executed in the order they are connected. Makes it cleaner to do cleanup procedures where they should make sense, unlike the global signal, where it has to be inferred by the widget instantiating order. --- rare/app.py | 6 +++--- rare/components/main_window.py | 16 ++++++++-------- rare/components/tabs/__init__.py | 6 +++++- rare/components/tabs/account/__init__.py | 6 +++++- rare/components/tray_icon.py | 14 +++++++++++--- 5 files changed, 32 insertions(+), 16 deletions(-) diff --git a/rare/app.py b/rare/app.py index 78eb13ce..b3bc055e 100644 --- a/rare/app.py +++ b/rare/app.py @@ -95,7 +95,7 @@ class App(RareApp): self.poke_timer() self.main_window = MainWindow() - self.main_window.exit_app.connect(self.exit_app) + self.main_window.exit_app.connect(self.on_exit_app) if not self.args.silent: self.main_window.show() @@ -103,11 +103,11 @@ class App(RareApp): if self.args.test_start: self.main_window.close() self.main_window = None - self.exit_app(0) + self.on_exit_app(0) @pyqtSlot() @pyqtSlot(int) - def exit_app(self, exit_code=0): + def on_exit_app(self, exit_code=0): threadpool = QThreadPool.globalInstance() threadpool.waitForDone() if self.timer is not None: diff --git a/rare/components/main_window.py b/rare/components/main_window.py index 93a3d042..384e923d 100644 --- a/rare/components/main_window.py +++ b/rare/components/main_window.py @@ -39,6 +39,7 @@ class MainWindow(QMainWindow): self.setWindowTitle("Rare - GUI for legendary") self.tab_widget = TabWidget(self) + self.tab_widget.exit_app.connect(self.on_exit_app) self.setCentralWidget(self.tab_widget) self.status_bar = QStatusBar() @@ -62,11 +63,9 @@ class MainWindow(QMainWindow): self.timer.timeout.connect(self.timer_finished) self.timer.start(1000) - self.signals.exit_app.connect(self.on_exit_app) - self.tray_icon: TrayIcon = TrayIcon(self) - self.tray_icon.exit_action.triggered.connect(self.on_exit_app) - self.tray_icon.start_rare.triggered.connect(self.show) + self.tray_icon.exit_app.connect(self.on_exit_app) + self.tray_icon.show_app.connect(self.show) self.tray_icon.activated.connect(lambda r: self.toggle() if r == self.tray_icon.DoubleClick else None) self.signals.send_notification.connect( @@ -107,6 +106,7 @@ class MainWindow(QMainWindow): self.resize(window_size) self.move(screen_rect.center() - self.rect().adjusted(0, 0, decor_width, decor_height).center()) + @pyqtSlot() def show(self) -> None: super(MainWindow, self).show() if not self._window_launched: @@ -147,8 +147,8 @@ class MainWindow(QMainWindow): return super(MainWindow, self).close() def closeEvent(self, e: QCloseEvent) -> None: - # lk: set to `True` by the `close()` method, overrides exiting to tray in `closeEvent()` - # lk: ensures exiting when instead of hiding when `close()` is called programmatically + # lk: `accept_close` is set to `True` by the `close()` method, overrides exiting to tray in `closeEvent()` + # lk: ensures exiting instead of hiding when `close()` is called programmatically if not self._accept_close: if self.settings.value("sys_tray", False, bool): self.hide() @@ -159,11 +159,11 @@ class MainWindow(QMainWindow): reply = QMessageBox.question( self, self.tr("Quit {}?").format(QApplication.applicationName()), - self.tr("There are active downloads. Do you really want to exit?"), + self.tr("There are active downloads. Are you sure you want to quit?"), buttons=(QMessageBox.Yes | QMessageBox.No), defaultButton=QMessageBox.No, ) - if reply == QMessageBox.No: + if reply == QMessageBox.Yes: # clear queue self.tab_widget.downloads_tab.queue_widget.update_queue([]) self.tab_widget.downloads_tab.stop_download() diff --git a/rare/components/tabs/__init__.py b/rare/components/tabs/__init__.py index c528959d..2474dbb6 100644 --- a/rare/components/tabs/__init__.py +++ b/rare/components/tabs/__init__.py @@ -1,4 +1,4 @@ -from PyQt5.QtCore import QSize +from PyQt5.QtCore import QSize, pyqtSignal from PyQt5.QtWidgets import QMenu, QTabWidget, QWidget, QWidgetAction, QShortcut from rare.shared import LegendaryCoreSingleton, GlobalSignalsSingleton, ArgumentsSingleton @@ -13,6 +13,9 @@ from rare.utils.misc import icon class TabWidget(QTabWidget): + # int: exit code + exit_app: pyqtSignal = pyqtSignal(int) + def __init__(self, parent): super(TabWidget, self).__init__(parent=parent) self.core = LegendaryCoreSingleton() @@ -55,6 +58,7 @@ class TabWidget(QTabWidget): self.setTabEnabled(disabled_tab + 1, False) self.account_widget = AccountWidget(self, self.downloads_tab) + self.account_widget.exit_app.connect(self.exit_app) account_action = QWidgetAction(self) account_action.setDefaultWidget(self.account_widget) account_button = TabButtonWidget("mdi.account-circle", "Account", fallback_icon="fa.user") diff --git a/rare/components/tabs/account/__init__.py b/rare/components/tabs/account/__init__.py index 55188f5e..e8729fb6 100644 --- a/rare/components/tabs/account/__init__.py +++ b/rare/components/tabs/account/__init__.py @@ -1,5 +1,6 @@ import webbrowser +from PyQt5.QtCore import pyqtSignal from PyQt5.QtWidgets import QWidget, QVBoxLayout, QMessageBox, QLabel, QPushButton from rare.shared import LegendaryCoreSingleton, GlobalSignalsSingleton @@ -7,6 +8,9 @@ from rare.utils.misc import icon class AccountWidget(QWidget): + # int: exit code + exit_app: pyqtSignal = pyqtSignal(int) + def __init__(self, parent, downloads_tab): super(AccountWidget, self).__init__(parent=parent) self.core = LegendaryCoreSingleton() @@ -56,4 +60,4 @@ class AccountWidget(QWidget): if reply == QMessageBox.Yes: self.core.lgd.invalidate_userdata() - self.signals.exit_app.emit(-133742) # restart exit code + self.exit_app.emit(-133742) # restart exit code diff --git a/rare/components/tray_icon.py b/rare/components/tray_icon.py index 8c29e30c..6c049daf 100644 --- a/rare/components/tray_icon.py +++ b/rare/components/tray_icon.py @@ -1,6 +1,7 @@ from logging import getLogger from typing import List +from PyQt5.QtCore import pyqtSignal from PyQt5.QtGui import QIcon from PyQt5.QtWidgets import QSystemTrayIcon, QMenu, QAction @@ -12,6 +13,11 @@ logger = getLogger("TrayIcon") class TrayIcon(QSystemTrayIcon): + # none: + show_app: pyqtSignal = pyqtSignal() + # int: exit code + exit_app: pyqtSignal = pyqtSignal(int) + def __init__(self, parent): super(TrayIcon, self).__init__(parent=parent) self.core = LegendaryCoreSingleton() @@ -22,8 +28,9 @@ class TrayIcon(QSystemTrayIcon): self.menu = QMenu() - self.start_rare = QAction("Rare") - self.menu.addAction(self.start_rare) + self.show_action = QAction("Rare") + self.show_action.triggered.connect(self.show_app) + self.menu.addAction(self.show_action) self.menu.addSeparator() self.text_action = QAction("Quick launch") @@ -53,7 +60,8 @@ class TrayIcon(QSystemTrayIcon): self.menu.addActions(self.game_actions) self.menu.addSeparator() - self.exit_action = QAction(self.tr("Exit")) + self.exit_action = QAction(self.tr("Quit")) + self.exit_action.triggered.connect(lambda: self.exit_app.emit(0)) self.menu.addAction(self.exit_action) self.setContextMenu(self.menu)