diff --git a/src/aare/gui/aaregui_logo.svg b/src/aare/gui/graphics/aaregui_logo.svg similarity index 100% rename from src/aare/gui/aaregui_logo.svg rename to src/aare/gui/graphics/aaregui_logo.svg diff --git a/src/aare/gui/gui.py b/src/aare/gui/gui.py index 66d7558b..9ce12798 100644 --- a/src/aare/gui/gui.py +++ b/src/aare/gui/gui.py @@ -4,28 +4,39 @@ import traceback from PySide6 import QtGui from PySide6.QtCore import QCommandLineParser, QCommandLineOption -from PySide6.QtWidgets import QApplication, QMessageBox - +from PySide6.QtWidgets import QApplication, QMessageBox, QSplashScreen, QProgressBar from aare.common.logger_config import setup_logger from aare.gui.main_window import MainWindow -#from aaregui.widgets.login import LoginDialog +from aare.gui.widgets.splash_screen import LoadingSplashScreen from aare.common.beamline import MXBeamline, mx_beamline, cfg_get from aare.gui.auth import auth logger = setup_logger("aareGUI") def main(): + """Wrapped gui as main function to make tests easier""" + splash = None try: + #define application app = QApplication(sys.argv) app.setApplicationName("AareGUI") app.setApplicationVersion("0.3.1") app.setOrganizationName("PSI") app.setOrganizationDomain("psi.ch") + + #set icon basedir = os.path.dirname(__file__) - icon_path = os.path.join(basedir, "aaregui_logo.svg") + icon_path = os.path.join(basedir, "graphics/aaregui_logo.svg") app.setWindowIcon(QtGui.QIcon(icon_path)) + #show splash screen + banner_path = os.path.join(basedir, "graphics/aare_banner.png") + splash_pix = QtGui.QPixmap(banner_path) + splash = LoadingSplashScreen(splash_pix) + splash.show() + splash.set_progress(10, "Initializing Application...") + # Create the parser parser = QCommandLineParser() parser.setApplicationDescription("PSI AareGUI") @@ -87,6 +98,7 @@ def main(): ) parser.addOption(predZmqOption) + splash.set_progress(30, "Parsing Arguments...") parser.process(app) base_url = parser.value(urlOption) @@ -107,6 +119,7 @@ def main(): default_image = None try: + splash.set_progress(50, f"Connecting to {base_url or 'backend'}...") token = auth(base_url) if not token or token.count(".") != 2: raise RuntimeError( @@ -114,7 +127,9 @@ def main(): "Please check the server is running (it may still be initialising)." ) logger.info("Authentication successful") + splash.set_progress(80, "Authentication successful...") except Exception as e: + splash.finish(None) logger.error(f"Cannot connect to AareDAQ server. Exiting. {e}") logger.error(traceback.format_exc()) QMessageBox.critical( @@ -124,7 +139,7 @@ def main(): ) sys.exit(1) - + splash.set_progress(90, "Loading Main Window...") win = MainWindow(base_url=base_url, token=token, default_image=default_image, @@ -133,9 +148,14 @@ def main(): beamline_cam_addr = default_beamline_cam_addr, gonio_cam_addr = default_gonio_cam_addr, gonio_cam_id = default_gonio_camera_id) + + splash.set_progress(100, "Ready") + splash.finish(win) win.show() sys.exit(app.exec()) + except Exception as e: + splash.finish(None) logger.error(f"Error starting GUI: {e}") logger.error(f"Traceback: {traceback.format_exc()}") diff --git a/src/aare/gui/widgets/splash_screen.py b/src/aare/gui/widgets/splash_screen.py new file mode 100644 index 00000000..6cc759f4 --- /dev/null +++ b/src/aare/gui/widgets/splash_screen.py @@ -0,0 +1,29 @@ +from PySide6.QtCore import Qt +from PySide6.QtWidgets import QSplashScreen, QProgressBar, QApplication + + +class LoadingSplashScreen(QSplashScreen): + def __init__(self, pixmap): + super().__init__(pixmap) + self.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.FramelessWindowHint) + self.progress = QProgressBar(self) + # Position the progress bar at the bottom of the splash screen + self.progress.setGeometry(10, self.size().height() - 30, self.size().width() - 20, 20) + self.progress.setStyleSheet(""" + QProgressBar { + border: 1px solid #444; + border-radius: 5px; + text-align: center; + background-color: #222; + color: white; + } + QProgressBar::chunk { + background-color: #0078d7; + } + """) + + def set_progress(self, value, message=None): + self.progress.setValue(value) + if message: + self.showMessage(message, Qt.AlignBottom | Qt.AlignCenter, Qt.white) + QApplication.processEvents() \ No newline at end of file