GUI: added an alert banner for major issues like tell and server dicsonnect/reconnect.
This commit is contained in:
+29
-17
@@ -9,8 +9,8 @@ from PySide6.QtWidgets import (
|
||||
QHBoxLayout,
|
||||
QVBoxLayout,
|
||||
QMessageBox,
|
||||
QApplication,
|
||||
QDockWidget, QTabWidget)
|
||||
QDockWidget,
|
||||
QTabWidget, QFrame, QSizePolicy, QLabel)
|
||||
|
||||
from aare.common.coordinate import Coordinate, SmargonCoordinate
|
||||
from aare.common.diffraction_geometry import DiffractionGeometry
|
||||
@@ -41,6 +41,7 @@ from aare.gui.threads.prediction_subscriber import PredictionSubscriber
|
||||
from aare.gui.threads.daq_worker import DAQWorker
|
||||
from aare.gui.threads.jfjoch_viewer import JFJochDBusClient
|
||||
from aare.gui.tutorials.tutorial_registration import register_tutorials
|
||||
from aare.gui.widgets.alert_banner import AlertBanner
|
||||
from aare.gui.widgets.camera_image import SampleCameraImageLabel
|
||||
from aare.gui.widgets.no_wheel_scroll_area import NoWheelScrollArea
|
||||
from aare.gui.widgets.status_bar import StatusBar
|
||||
@@ -98,15 +99,23 @@ class MainWindow(QMainWindow):
|
||||
|
||||
self.setStyleSheet("background-color: rgb(216, 228, 253);")
|
||||
|
||||
top_widget = QWidget(parent=self)
|
||||
root_widget = QWidget(parent=self)
|
||||
root_layout = QVBoxLayout(root_widget)
|
||||
root_layout.setContentsMargins(0, 0, 0, 0)
|
||||
root_layout.setSpacing(0)
|
||||
|
||||
self.alert_banner = AlertBanner(parent=root_widget)
|
||||
root_layout.addWidget(self.alert_banner)
|
||||
|
||||
top_widget = QWidget(parent=root_widget)
|
||||
top_widget_layout = QHBoxLayout(top_widget)
|
||||
top_widget.setLayout(top_widget_layout)
|
||||
|
||||
diffraction = DiffractionGeometry(
|
||||
energy_keV=12.4,
|
||||
dtz_mm=100,
|
||||
detector_size_pxl=(1553,1630),
|
||||
pixel_size_mm=0.150, #PILATUS 4
|
||||
detector_size_pxl=(1553, 1630),
|
||||
pixel_size_mm=0.150, # PILATUS 4
|
||||
beam_center_pxl=(750, 750),
|
||||
detector_description="PILATUS 4",
|
||||
detector_serial_number="1",
|
||||
@@ -114,7 +123,7 @@ class MainWindow(QMainWindow):
|
||||
poni_rot2_rad=-0.003839724
|
||||
)
|
||||
|
||||
geom = SampleGeometryModel(beam_location_pxl=Coordinate(x=1000,y=1000),
|
||||
geom = SampleGeometryModel(beam_location_pxl=Coordinate(x=1000, y=1000),
|
||||
pixel_in_mm=0.001,
|
||||
aerotech=Coordinate(),
|
||||
smargon=SmargonCoordinate(sh_mm=Coordinate(), phi_deg=0, chi_deg=0),
|
||||
@@ -133,7 +142,6 @@ class MainWindow(QMainWindow):
|
||||
raster_mgr=self.raster,
|
||||
diffraction=diffraction)
|
||||
|
||||
|
||||
top_widget_layout.addWidget(collection_controls_scroll)
|
||||
collection_controls_scroll.setWidget(self.data_collection)
|
||||
collection_controls_scroll.setHorizontalScrollBarPolicy(
|
||||
@@ -141,14 +149,14 @@ class MainWindow(QMainWindow):
|
||||
)
|
||||
collection_controls_scroll.setFixedWidth(self.data_collection.set_width + 10)
|
||||
|
||||
|
||||
self.video_tab = QTabWidget(parent=top_widget)
|
||||
|
||||
self.sample_camera = SampleCameraImageLabel(geom=geom, raster=self.raster, parent=top_widget, default_image=default_image)
|
||||
self.sample_camera = SampleCameraImageLabel(geom=geom, raster=self.raster, parent=top_widget,
|
||||
default_image=default_image)
|
||||
|
||||
self.beamline_view_container = QWidget(parent=top_widget)
|
||||
self.beamline_view_layout = QVBoxLayout(self.beamline_view_container)
|
||||
self.beamline_view_layout.setContentsMargins(0,0,0,0)
|
||||
self.beamline_view_layout.setContentsMargins(0, 0, 0, 0)
|
||||
self.beamline_view_layout.setSpacing(6)
|
||||
|
||||
self.beamline_view_1_combined = VideoGraphicsView()
|
||||
@@ -165,7 +173,7 @@ class MainWindow(QMainWindow):
|
||||
self.beamline_view_layout.addWidget(self.beamline_view)
|
||||
|
||||
self.gonio_view = VideoGraphicsView()
|
||||
#TODO add option to change cameras for gonio_camera_thread
|
||||
# TODO add option to change cameras for gonio_camera_thread
|
||||
if gonio_cam_addr and gonio_cam_id:
|
||||
self.gonio_camera_thread = VideoThread(ip=gonio_cam_addr, camera=gonio_cam_id)
|
||||
self.gonio_camera_thread.frame_ready.connect(self.gonio_view.update_frame)
|
||||
@@ -190,8 +198,8 @@ class MainWindow(QMainWindow):
|
||||
)
|
||||
beamline_controls_scroll.setFixedWidth(self.beamline.set_width + 10)
|
||||
|
||||
self.tell_samples = TellSamplePanel(samples=SampleShortInfoList(s = []))
|
||||
self.ref_tools_panel = ReferenceToolsPanel(samples=SampleShortInfoList(s = []))
|
||||
self.tell_samples = TellSamplePanel(samples=SampleShortInfoList(s=[]))
|
||||
self.ref_tools_panel = ReferenceToolsPanel(samples=SampleShortInfoList(s=[]))
|
||||
self.job_list_panel = SampleQueuePanel()
|
||||
|
||||
self.tell_samples_dock = QDockWidget("Sample List", self)
|
||||
@@ -227,7 +235,8 @@ class MainWindow(QMainWindow):
|
||||
self.face_panel_dock = QDockWidget("Face detection", self)
|
||||
self.face_panel_dock.setObjectName("face_panel_dock")
|
||||
self.face_panel_dock.setWidget(self.face_panel)
|
||||
self.face_panel_dock.setAllowedAreas(Qt.DockWidgetArea.RightDockWidgetArea | Qt.DockWidgetArea.LeftDockWidgetArea)
|
||||
self.face_panel_dock.setAllowedAreas(
|
||||
Qt.DockWidgetArea.RightDockWidgetArea | Qt.DockWidgetArea.LeftDockWidgetArea)
|
||||
self.addDockWidget(Qt.DockWidgetArea.RightDockWidgetArea, self.face_panel_dock)
|
||||
self.face_panel_dock.hide()
|
||||
|
||||
@@ -235,7 +244,8 @@ class MainWindow(QMainWindow):
|
||||
self.fluor_panel_dock = QDockWidget("Fluorescence", self)
|
||||
self.fluor_panel_dock.setObjectName("fluor_panel_dock")
|
||||
self.fluor_panel_dock.setWidget(self.fluor_panel)
|
||||
self.fluor_panel_dock.setAllowedAreas(Qt.DockWidgetArea.TopDockWidgetArea | Qt.DockWidgetArea.BottomDockWidgetArea | Qt.DockWidgetArea.RightDockWidgetArea)
|
||||
self.fluor_panel_dock.setAllowedAreas(
|
||||
Qt.DockWidgetArea.TopDockWidgetArea | Qt.DockWidgetArea.BottomDockWidgetArea | Qt.DockWidgetArea.RightDockWidgetArea)
|
||||
self.addDockWidget(Qt.DockWidgetArea.BottomDockWidgetArea, self.fluor_panel_dock)
|
||||
self.fluor_panel_dock.hide()
|
||||
|
||||
@@ -260,7 +270,8 @@ class MainWindow(QMainWindow):
|
||||
self.addDockWidget(Qt.DockWidgetArea.RightDockWidgetArea, self.smargon_trace_dock)
|
||||
self.smargon_trace_dock.hide()
|
||||
|
||||
self.setCentralWidget(top_widget)
|
||||
root_layout.addWidget(top_widget)
|
||||
self.setCentralWidget(root_widget)
|
||||
|
||||
self.setWindowTitle("AareGUI")
|
||||
self.create_menu_bar()
|
||||
@@ -343,7 +354,7 @@ class MainWindow(QMainWindow):
|
||||
self._samcam_source_timer.start()
|
||||
|
||||
#
|
||||
# self.data_collection.helical.helical_scan.connect(self.worker.helical_scan)
|
||||
# self.data_collection.helical.helical_scan.connect(self.worker.helical_scan)
|
||||
# self.data_collection.helical.update_bookmarks.connect(
|
||||
# self.camera_image.update_bookmarks
|
||||
# )
|
||||
@@ -447,6 +458,7 @@ class MainWindow(QMainWindow):
|
||||
self.daq.fluorimeter_spectrum_update.connect(lambda: self.fluor_panel_dock.setVisible(True))
|
||||
|
||||
self.daq.status_message.connect(self.status_bar.show_connection_message)
|
||||
self.daq.status_message.connect(self.alert_banner.show_message)
|
||||
|
||||
register_tutorials(self, self.tutorial_manager)
|
||||
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
from PySide6.QtCore import QTimer, Slot, Qt
|
||||
from PySide6.QtGui import QColor
|
||||
from PySide6.QtWidgets import QFrame, QHBoxLayout, QLabel, QSizePolicy, QGraphicsDropShadowEffect
|
||||
|
||||
from aare.common.logger_config import setup_logger
|
||||
|
||||
logger = setup_logger("aareGUI")
|
||||
|
||||
|
||||
class AlertBanner(QFrame):
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
|
||||
self._clear_timer = QTimer(self)
|
||||
self._clear_timer.setSingleShot(True)
|
||||
self._clear_timer.timeout.connect(self.clear_message)
|
||||
|
||||
self._label = QLabel("", self)
|
||||
self._label.setWordWrap(True)
|
||||
self._label.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
|
||||
layout = QHBoxLayout(self)
|
||||
layout.setContentsMargins(24, 12, 24, 12)
|
||||
layout.addWidget(self._label)
|
||||
|
||||
shadow = QGraphicsDropShadowEffect(self)
|
||||
shadow.setBlurRadius(18)
|
||||
shadow.setOffset(0, 3)
|
||||
shadow.setColor(QColor(0, 0, 0, 55))
|
||||
self.setGraphicsEffect(shadow)
|
||||
|
||||
self.setVisible(False)
|
||||
self.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed)
|
||||
|
||||
@Slot(str, bool)
|
||||
def show_message(self, msg: str, is_error: bool = True):
|
||||
self._clear_timer.stop()
|
||||
|
||||
if not msg:
|
||||
self.clear_message()
|
||||
return
|
||||
|
||||
if is_error:
|
||||
decorated = f"🛑 {msg} 🛑"
|
||||
self.setStyleSheet(
|
||||
"QFrame {"
|
||||
" background-color: #fbe4e6;"
|
||||
" border: 2px solid #d97a84;"
|
||||
" border-radius: 12px;"
|
||||
" margin: 8px 12px 8px 12px;"
|
||||
"}"
|
||||
"QLabel {"
|
||||
" color: #8f1d2c;"
|
||||
" font-weight: 700;"
|
||||
" font-size: 20px;"
|
||||
" padding: 2px 6px 2px 6px;"
|
||||
"}"
|
||||
)
|
||||
else:
|
||||
decorated = f"✅ {msg} ✅"
|
||||
self.setStyleSheet(
|
||||
"QFrame {"
|
||||
" background-color: #e7f6ea;"
|
||||
" border: 2px solid #7bbf8e;"
|
||||
" border-radius: 12px;"
|
||||
" margin: 8px 12px 8px 12px;"
|
||||
"}"
|
||||
"QLabel {"
|
||||
" color: #1f6a3a;"
|
||||
" font-weight: 700;"
|
||||
" font-size: 20px;"
|
||||
" padding: 2px 6px 2px 6px;"
|
||||
"}"
|
||||
)
|
||||
self._clear_timer.start(5000)
|
||||
|
||||
self._label.setText(decorated)
|
||||
self.setVisible(True)
|
||||
|
||||
@Slot()
|
||||
def clear_message(self):
|
||||
self._clear_timer.stop()
|
||||
self._label.clear()
|
||||
self.setVisible(False)
|
||||
Reference in New Issue
Block a user