diff --git a/src/gui/ALConfigWidget.py b/src/gui/ALConfigWidget.py index eea0bb3..e06727b 100644 --- a/src/gui/ALConfigWidget.py +++ b/src/gui/ALConfigWidget.py @@ -42,6 +42,7 @@ from gui.ALUserTreeWidget import ( ALUserTreeWidget ) from gui.ALWebDriverDownloadDialog import ALWebDriverDownloadDialog +from gui.ALWidgetMixin import CenterOnParentMixin from gui.resources.ui.Ui_ALConfigWidget import Ui_ALConfigWidget from interfaces.ConfigProvider import ( CfgKey, @@ -52,7 +53,7 @@ from utils.JSONReader import JSONReader from utils.JSONWriter import JSONWriter -class ALConfigWidget(QWidget, Ui_ALConfigWidget): +class ALConfigWidget(CenterOnParentMixin, QWidget, Ui_ALConfigWidget): configWidgetIsClosed = Signal() @@ -110,29 +111,6 @@ class ALConfigWidget(QWidget, Ui_ALConfigWidget): self.ConfirmButton.clicked.connect(self.onConfirmButtonClicked) self.CancelButton.clicked.connect(self.onCancelButtonClicked) - def showEvent( - self, - event - ): - - result = super().showEvent(event) - - screen_rect = self.screen().geometry() - target_pos = self.parent().geometry().center() - target_pos.setX(target_pos.x() - self.width()//2) - target_pos.setY(target_pos.y() - self.height()//2) - if target_pos.x() < 0: - target_pos.setX(0) - if target_pos.x() + self.width() > screen_rect.width(): - target_pos.setX(screen_rect.width() - self.width()) - if target_pos.y() < 0: - target_pos.setY(0) - if target_pos.y() + self.height() > screen_rect.height(): - target_pos.setY(screen_rect.height() - self.height()) - self.move(target_pos) - - return result - def closeEvent( self, event: QCloseEvent diff --git a/src/gui/ALSeatMapSelectDialog.py b/src/gui/ALSeatMapSelectDialog.py index 0602dc5..67c812b 100644 --- a/src/gui/ALSeatMapSelectDialog.py +++ b/src/gui/ALSeatMapSelectDialog.py @@ -24,9 +24,9 @@ from PySide6.QtWidgets import ( ) from gui.ALSeatMapView import ALSeatMapView +from gui.ALWidgetMixin import CenterOnParentMixin - -class ALSeatMapSelectDialog(QDialog): +class ALSeatMapSelectDialog(CenterOnParentMixin, QDialog): seatMapSelectDialogIsClosed = Signal(list) @@ -96,29 +96,6 @@ class ALSeatMapSelectDialog(QDialog): self.ConfirmButton.clicked.connect(self.onConfirmButtonClicked) self.CancelButton.clicked.connect(self.onCancelButtonClicked) - def showEvent( - self, - event - ): - - result = super().showEvent(event) - - screen_rect = self.screen().geometry() - target_pos = self.parent().geometry().center() - target_pos.setX(target_pos.x() - self.width()//2) - target_pos.setY(target_pos.y() - self.height()//2) - if target_pos.x() < 0: - target_pos.setX(0) - if target_pos.x() + self.width() > screen_rect.width(): - target_pos.setX(screen_rect.width() - self.width()) - if target_pos.y() < 0: - target_pos.setY(0) - if target_pos.y() + self.height() > screen_rect.height(): - target_pos.setY(screen_rect.height() - self.height()) - self.move(target_pos) - - return result - def closeEvent( self, event: QCloseEvent diff --git a/src/gui/ALSettingsWidget.py b/src/gui/ALSettingsWidget.py index 8c0711e..fd3d786 100644 --- a/src/gui/ALSettingsWidget.py +++ b/src/gui/ALSettingsWidget.py @@ -19,8 +19,7 @@ from PySide6.QtCore import ( Slot ) from PySide6.QtGui import ( - QCloseEvent, - QShowEvent + QCloseEvent ) from PySide6.QtWidgets import ( QApplication, @@ -38,6 +37,7 @@ from managers.theme.ThemeManager import( instance as themeInstance ) +from gui.ALWidgetMixin import CenterOnParentMixin from gui.resources.ui.Ui_ALSettingsWidget import Ui_ALSettingsWidget from interfaces.ConfigProvider import ( CfgKey, @@ -83,7 +83,7 @@ def _restartApp( QProcess.startDetached(sys.executable, sys.argv) -class ALSettingsWidget(QWidget, Ui_ALSettingsWidget): +class ALSettingsWidget(CenterOnParentMixin, QWidget, Ui_ALSettingsWidget): settingsWidgetIsClosed = Signal() @@ -102,6 +102,14 @@ class ALSettingsWidget(QWidget, Ui_ALSettingsWidget): self.connectSignals() self.loadSettings() + def closeEvent( + self, + event: QCloseEvent + ): + + self.settingsWidgetIsClosed.emit() + super().closeEvent(event) + def modifyUi( self ): @@ -153,35 +161,6 @@ class ALSettingsWidget(QWidget, Ui_ALSettingsWidget): self.ApplyButton.clicked.connect(self.onApplyButtonClicked) self.ConfirmButton.clicked.connect(self.onConfirmButtonClicked) - def showEvent( - self, - event: QShowEvent - ): - - result = super().showEvent(event) - screen_rect = self.screen().geometry() - target_pos = self.parent().geometry().center() - target_pos.setX(target_pos.x() - self.width()//2) - target_pos.setY(target_pos.y() - self.height()//2) - if target_pos.x() < 0: - target_pos.setX(0) - if target_pos.x() + self.width() > screen_rect.width(): - target_pos.setX(screen_rect.width() - self.width()) - if target_pos.y() < 0: - target_pos.setY(0) - if target_pos.y() + self.height() > screen_rect.height(): - target_pos.setY(screen_rect.height() - self.height()) - self.move(target_pos) - return result - - def closeEvent( - self, - event: QCloseEvent - ): - - self.settingsWidgetIsClosed.emit() - super().closeEvent(event) - def loadSettings( self ): diff --git a/src/gui/ALTimerTaskManageWidget.py b/src/gui/ALTimerTaskManageWidget.py index c6e191f..8b9ac30 100644 --- a/src/gui/ALTimerTaskManageWidget.py +++ b/src/gui/ALTimerTaskManageWidget.py @@ -43,6 +43,7 @@ from gui.ALTimerTaskAddDialog import ( ALTimerTaskStatus ) from gui.ALTimerTaskHistoryDialog import ALTimerTaskHistoryDialog +from gui.ALWidgetMixin import CenterOnParentMixin from gui.resources.ui.Ui_ALTimerTaskManageWidget import Ui_ALTimerTaskManageWidget from interfaces.ConfigProvider import ( CfgKey, @@ -189,7 +190,7 @@ class ALTimerTaskItemWidget(QWidget): Menu.exec(self.mapToGlobal(pos)) -class ALTimerTaskManageWidget(QWidget, Ui_ALTimerTaskManageWidget): +class ALTimerTaskManageWidget(CenterOnParentMixin, QWidget, Ui_ALTimerTaskManageWidget): class SortPolicy(Enum): @@ -299,29 +300,6 @@ class ALTimerTaskManageWidget(QWidget, Ui_ALTimerTaskManageWidget): ) return False - def showEvent( - self, - event - ): - - result = super().showEvent(event) - - screen_rect = self.screen().geometry() - target_pos = self.parent().geometry().center() - target_pos.setX(target_pos.x() - self.width()//2) - target_pos.setY(target_pos.y() - self.height()//2) - if target_pos.x() < 0: - target_pos.setX(0) - if target_pos.x() + self.width() > screen_rect.width(): - target_pos.setX(screen_rect.width() - self.width()) - if target_pos.y() < 0: - target_pos.setY(0) - if target_pos.y() + self.height() > screen_rect.height(): - target_pos.setY(screen_rect.height() - self.height()) - self.move(target_pos) - - return result - def closeEvent( self, event: QCloseEvent diff --git a/src/gui/ALWebDriverDownloadDialog.py b/src/gui/ALWebDriverDownloadDialog.py index 42ac710..aaf619e 100644 --- a/src/gui/ALWebDriverDownloadDialog.py +++ b/src/gui/ALWebDriverDownloadDialog.py @@ -38,6 +38,7 @@ from managers.driver.WebDriverManager import ( WebDriverStatus ) from gui.ALStatusLabel import ALStatusLabel +from gui.ALWidgetMixin import CenterOnParentMixin class DownloadWorker(QThread): @@ -123,7 +124,7 @@ class DownloadWorker(QThread): self.wait() -class ALWebDriverDownloadDialog(QDialog): +class ALWebDriverDownloadDialog(CenterOnParentMixin, QDialog): def __init__( self, @@ -152,28 +153,6 @@ class ALWebDriverDownloadDialog(QDialog): self.initializeDriverManager() self.refreshDriverList() - def showEvent( - self, - event - ): - - result = super().showEvent(event) - if self.parent(): - screen_rect = self.screen().geometry() - target_pos = self.parent().geometry().center() - target_pos.setX(target_pos.x() - self.width()//2) - target_pos.setY(target_pos.y() - self.height()//2) - if target_pos.x() < 0: - target_pos.setX(0) - if target_pos.x() + self.width() > screen_rect.width(): - target_pos.setX(screen_rect.width() - self.width()) - if target_pos.y() < 0: - target_pos.setY(0) - if target_pos.y() + self.height() > screen_rect.height(): - target_pos.setY(screen_rect.height() - self.height()) - self.move(target_pos) - return result - def setupUi( self ): diff --git a/src/gui/ALWidgetMixin.py b/src/gui/ALWidgetMixin.py new file mode 100644 index 0000000..0e95ebf --- /dev/null +++ b/src/gui/ALWidgetMixin.py @@ -0,0 +1,49 @@ +# -*- coding: utf-8 -*- +""" +Copyright (c) 2026 KenanZhu. +All rights reserved. + +This software is provided "as is", without any warranty of any kind. +You may use, modify, and distribute this file under the terms of the MIT License. +See the LICENSE file for details. +""" +from PySide6.QtGui import QShowEvent + + +class CenterOnParentMixin: + """ + Mixin that centres the widget relative to its parent on first show, + clamping the position to the screen bounds. + + Usage:: + + class MyWidget(CenterOnParentMixin, QWidget, Ui_MyWidget): + pass + + class MyDialog(CenterOnParentMixin, QDialog): + pass + + The mixin must appear **before** QWidget / QDialog in the base list + so that ``super().showEvent(event)`` resolves up the MRO correctly. + """ + + def showEvent( + self, + event: QShowEvent + ): + + super().showEvent(event) + if self.parent(): + screen_rect = self.screen().geometry() + target_pos = self.parent().geometry().center() + target_pos.setX(target_pos.x() - self.width() // 2) + target_pos.setY(target_pos.y() - self.height() // 2) + if target_pos.x() < 0: + target_pos.setX(0) + if target_pos.x() + self.width() > screen_rect.width(): + target_pos.setX(screen_rect.width() - self.width()) + if target_pos.y() < 0: + target_pos.setY(0) + if target_pos.y() + self.height() > screen_rect.height(): + target_pos.setY(screen_rect.height() - self.height()) + self.move(target_pos)