0
0
mirror of https://github.com/bec-project/bec_widgets.git synced 2025-07-14 03:31:50 +02:00

fix: Alignment 1D update, make app window a main window (in .ui file)

This commit is contained in:
2024-10-03 18:11:20 +02:00
parent af9655de0c
commit 0015f0e2d6
2 changed files with 453 additions and 811 deletions

View File

@ -8,45 +8,54 @@ from typing import Optional
from bec_lib.device import Positioner as BECPositioner from bec_lib.device import Positioner as BECPositioner
from bec_lib.device import Signal as BECSignal from bec_lib.device import Signal as BECSignal
from bec_lib.endpoints import MessageEndpoints from bec_lib.endpoints import MessageEndpoints
from bec_lib.logger import bec_logger
from qtpy.QtCore import QSize, Signal from qtpy.QtCore import QSize, Signal
from qtpy.QtGui import QIcon from qtpy.QtGui import QIcon
from qtpy.QtWidgets import QCheckBox, QDoubleSpinBox, QMainWindow, QPushButton, QSpinBox from qtpy.QtWidgets import (
QApplication,
QCheckBox,
QDoubleSpinBox,
QMainWindow,
QPushButton,
QSpinBox,
)
import bec_widgets import bec_widgets
from bec_widgets.qt_utils.error_popups import SafeSlot as Slot from bec_widgets.qt_utils.error_popups import SafeSlot as Slot
from bec_widgets.qt_utils.toolbar import WidgetAction from bec_widgets.qt_utils.toolbar import WidgetAction
from bec_widgets.utils import UILoader from bec_widgets.utils import UILoader
from bec_widgets.utils.bec_dispatcher import BECDispatcher
from bec_widgets.utils.bec_widget import BECWidget from bec_widgets.utils.bec_widget import BECWidget
from bec_widgets.utils.colors import get_accent_colors from bec_widgets.utils.colors import get_accent_colors
from bec_widgets.widgets.bec_progressbar.bec_progressbar import BECProgressBar from bec_widgets.widgets.bec_progressbar.bec_progressbar import BECProgressBar
from bec_widgets.widgets.device_line_edit.device_line_edit import DeviceLineEdit from bec_widgets.widgets.device_line_edit.device_line_edit import DeviceLineEdit
from bec_widgets.widgets.lmfit_dialog.lmfit_dialog import LMFitDialog from bec_widgets.widgets.lmfit_dialog.lmfit_dialog import LMFitDialog
from bec_widgets.widgets.positioner_box.positioner_box import PositionerBox from bec_widgets.widgets.positioner_box.positioner_box import PositionerBox
from bec_widgets.widgets.positioner_group.positioner_group import PositionerGroup
from bec_widgets.widgets.stop_button.stop_button import StopButton from bec_widgets.widgets.stop_button.stop_button import StopButton
from bec_widgets.widgets.toggle.toggle import ToggleSwitch from bec_widgets.widgets.toggle.toggle import ToggleSwitch
from bec_widgets.widgets.waveform.waveform_widget import BECWaveformWidget from bec_widgets.widgets.waveform.waveform_widget import BECWaveformWidget
MODULE_PATH = os.path.dirname(bec_widgets.__file__) MODULE_PATH = os.path.dirname(bec_widgets.__file__)
logger = bec_logger.logger
class Alignment1D(BECWidget, QMainWindow): class Alignment1D:
"""Alignment GUI to perform 1D scans""" """Alignment GUI to perform 1D scans"""
# Emit a signal when a motion is ongoing
motion_is_active = Signal(bool)
def __init__(self, client=None, gui_id: Optional[str] = None) -> None: def __init__(self, client=None, gui_id: Optional[str] = None) -> None:
"""Initialise the widget """Initialization
Args: Args:
parent: Parent widget. config: Configuration of the application.
config: Configuration of the widget.
client: BEC client object. client: BEC client object.
gui_id: GUI ID. gui_id: GUI ID.
""" """
super().__init__(client=client, gui_id=gui_id) self.bec_dispatcher = BECDispatcher(client=client)
QMainWindow.__init__(self) self.client = self.bec_dispatcher.client if client is None else client
self.get_bec_shortcuts() QApplication.instance().aboutToQuit.connect(self.close)
self.dev = self.client.device_manager.devices
self._accent_colors = get_accent_colors() self._accent_colors = get_accent_colors()
self.ui_file = "alignment_1d.ui" self.ui_file = "alignment_1d.ui"
self.ui = None self.ui = None
@ -57,28 +66,25 @@ class Alignment1D(BECWidget, QMainWindow):
def init_ui(self): def init_ui(self):
"""Initialise the UI from QT Designer file""" """Initialise the UI from QT Designer file"""
current_path = os.path.dirname(__file__) current_path = os.path.dirname(__file__)
self.ui = UILoader(self).loader(os.path.join(current_path, self.ui_file)) self.ui = UILoader(None).loader(os.path.join(current_path, self.ui_file))
self.setCentralWidget(self.ui)
# Customize the plotting widget # Customize the plotting widget
self.waveform = self.ui.findChild(BECWaveformWidget, "bec_waveform_widget") self.waveform = self.ui.findChild(BECWaveformWidget, "bec_waveform_widget")
self._customise_bec_waveform_widget() self._customise_bec_waveform_widget()
# Setup comboboxes for motor and signal selection # Setup comboboxes for motor and signal selection
# FIXME after changing the filtering in the combobox # FIXME after changing the filtering in the combobox
self._setup_motor_combobox()
self._setup_signal_combobox() self._setup_signal_combobox()
# Setup motor indicator # Setup motor indicator
self._setup_motor_indicator() self._setup_motor_indicator()
# Connect spinboxes to scan Control
self._setup_scan_control()
# Setup progress bar # Setup progress bar
self._setup_progress_bar() self._setup_progress_bar()
# Add actions buttons # Add actions buttons
self._customise_buttons() self._customise_buttons()
# Customize the positioner box
self._customize_positioner_box()
# Hook scaninfo updates # Hook scaninfo updates
self.bec_dispatcher.connect_slot(self.scan_status_callback, MessageEndpoints.scan_status()) self.bec_dispatcher.connect_slot(self.scan_status_callback, MessageEndpoints.scan_status())
def show(self):
return self.ui.show()
############################## ##############################
############ SLOTS ########### ############ SLOTS ###########
############################## ##############################
@ -87,10 +93,8 @@ class Alignment1D(BECWidget, QMainWindow):
def scan_status_callback(self, content: dict, _) -> None: def scan_status_callback(self, content: dict, _) -> None:
"""This slot allows to enable/disable the UI critical components when a scan is running""" """This slot allows to enable/disable the UI critical components when a scan is running"""
if content["status"] in ["open"]: if content["status"] in ["open"]:
self.motion_is_active.emit(True)
self.enable_ui(False) self.enable_ui(False)
elif content["status"] in ["aborted", "halted", "closed"]: elif content["status"] in ["aborted", "halted", "closed"]:
self.motion_is_active.emit(False)
self.enable_ui(True) self.enable_ui(True)
@Slot(tuple) @Slot(tuple)
@ -133,15 +137,11 @@ class Alignment1D(BECWidget, QMainWindow):
def enable_ui(self, enable: bool) -> None: def enable_ui(self, enable: bool) -> None:
"""Enable or disable the UI components""" """Enable or disable the UI components"""
# Enable/disable motor and signal selection # Enable/disable motor and signal selection
self.ui.device_combobox.setEnabled(enable)
self.ui.device_combobox_2.setEnabled(enable) self.ui.device_combobox_2.setEnabled(enable)
# Enable/disable DAP selection # Enable/disable DAP selection
self.ui.dap_combo_box.setEnabled(enable) self.ui.dap_combo_box.setEnabled(enable)
# Enable/disable Scan Button # Enable/disable Scan Button
self.ui.scan_button.setEnabled(enable) # self.ui.scan_button.setEnabled(enable)
# Positioner control line
# pylint: disable=protected-access
self.ui.positioner_box._toogle_enable_buttons(enable)
# Disable move to buttons in LMFitDialog # Disable move to buttons in LMFitDialog
self.ui.findChild(LMFitDialog).set_actions_enabled(enable) self.ui.findChild(LMFitDialog).set_actions_enabled(enable)
@ -154,49 +154,20 @@ class Alignment1D(BECWidget, QMainWindow):
fit_dialog = self.ui.findChild(LMFitDialog) fit_dialog = self.ui.findChild(LMFitDialog)
fit_dialog.active_action_list = ["center", "center1", "center2"] fit_dialog.active_action_list = ["center", "center1", "center2"]
fit_dialog.move_action.connect(self.move_to_center) fit_dialog.move_action.connect(self.move_to_center)
scan_button = self.ui.findChild(QPushButton, "scan_button")
scan_button.setStyleSheet(
f"""
QPushButton:enabled {{ background-color: {self._accent_colors.success.name()};color: white; }}
QPushButton:disabled {{ background-color: grey;color: white; }}
"""
)
stop_button = self.ui.findChild(StopButton) stop_button = self.ui.findChild(StopButton)
stop_button.button.setText("Stop and Clear Queue") stop_button.button.setText("Stop and Clear Queue")
stop_button.button.clicked.connect(self.clear_queue) stop_button.button.clicked.connect(self.clear_queue)
def _customise_bec_waveform_widget(self) -> None: def _customise_bec_waveform_widget(self) -> None:
"""Customise the BEC Waveform Widget, i.e. clear the toolbar, add the DAP ROI selection to the toolbar. """Customise the BEC Waveform Widget, i.e. clear the toolbar"""
We also move the scan_control widget which is fully hidden and solely used for setting up the scan parameters to the toolbar.
"""
self.waveform.toolbar.clear() self.waveform.toolbar.clear()
toggle_switch = self.ui.findChild(ToggleSwitch, "toggle_switch")
scan_control = self.ui.scan_control
self.waveform.toolbar.populate_toolbar(
{
"label": WidgetAction(label="ENABLE DAP ROI", widget=toggle_switch),
"scan_control": WidgetAction(widget=scan_control),
},
self.waveform,
)
def _setup_motor_indicator(self) -> None: def _setup_motor_indicator(self) -> None:
"""Setup the arrow item""" """Setup the arrow item"""
self.waveform.waveform.tick_item.add_to_plot() self.waveform.waveform.tick_item.add_to_plot()
positioner_box = self.ui.findChild(PositionerBox) positioner_box = self.ui.findChild(PositionerGroup)
positioner_box.position_update.connect(self.waveform.waveform.tick_item.set_position) positioner_box.position_update.connect(self.waveform.waveform.tick_item.set_position)
try: self.waveform.waveform.tick_item.set_position(0)
pos = float(positioner_box.ui.readback.text())
except ValueError:
pos = 0
self.waveform.waveform.tick_item.set_position(pos)
def _setup_motor_combobox(self) -> None:
"""Setup motor selection"""
# FIXME after changing the filtering in the combobox
motors = [name for name in self.dev if isinstance(self.dev.get(name), BECPositioner)]
self.ui.device_combobox.setCurrentText(motors[0])
self.ui.device_combobox.set_device_filter("Positioner")
def _setup_signal_combobox(self) -> None: def _setup_signal_combobox(self) -> None:
"""Setup signal selection""" """Setup signal selection"""
@ -205,31 +176,6 @@ class Alignment1D(BECWidget, QMainWindow):
self.ui.device_combobox_2.setCurrentText(signals[0]) self.ui.device_combobox_2.setCurrentText(signals[0])
self.ui.device_combobox_2.set_device_filter("Signal") self.ui.device_combobox_2.set_device_filter("Signal")
def _setup_scan_control(self) -> None:
"""Setup scan control, connect spin and check boxes to the scan_control widget"""
# Connect motor
device_line_edit = self.ui.scan_control.arg_box.findChild(DeviceLineEdit)
self.ui.device_combobox.currentTextChanged.connect(device_line_edit.setText)
device_line_edit.setText(self.ui.device_combobox.currentText())
# Connect start, stop, step, exp_time and relative check box
spin_boxes = self.ui.scan_control.arg_box.findChildren(QDoubleSpinBox)
start = self.ui.findChild(QDoubleSpinBox, "linescan_start")
start.valueChanged.connect(spin_boxes[0].setValue)
stop = self.ui.findChild(QDoubleSpinBox, "linescan_stop")
stop.valueChanged.connect(spin_boxes[1].setValue)
step = self.ui.findChild(QSpinBox, "linescan_step")
step.valueChanged.connect(
self.ui.scan_control.kwarg_boxes[0].findChildren(QSpinBox)[0].setValue
)
exp_time = self.ui.findChild(QDoubleSpinBox, "linescan_exp_time")
exp_time.valueChanged.connect(
self.ui.scan_control.kwarg_boxes[1].findChildren(QDoubleSpinBox)[0].setValue
)
relative = self.ui.findChild(QCheckBox, "linescan_relative")
relative.toggled.connect(
self.ui.scan_control.kwarg_boxes[0].findChildren(QCheckBox)[0].setChecked
)
def _setup_progress_bar(self) -> None: def _setup_progress_bar(self) -> None:
"""Setup progress bar""" """Setup progress bar"""
# FIXME once the BECScanProgressBar is implemented # FIXME once the BECScanProgressBar is implemented
@ -238,18 +184,16 @@ class Alignment1D(BECWidget, QMainWindow):
self.ui.bec_waveform_widget.new_scan.connect(self.reset_progress_bar) self.ui.bec_waveform_widget.new_scan.connect(self.reset_progress_bar)
self.bec_dispatcher.connect_slot(self.update_progress_bar, MessageEndpoints.scan_progress()) self.bec_dispatcher.connect_slot(self.update_progress_bar, MessageEndpoints.scan_progress())
def _customize_positioner_box(self) -> None: def close(self):
"""Customize the positioner Box, i.e. remove the stop button""" logger.info("Disconnecting", repr(self.bec_dispatcher))
box = self.ui.findChild(PositionerBox) self.bec_dispatcher.disconnect_all()
box.ui.stop.setVisible(False) logger.info("Shutting down BEC Client", repr(self.client))
box.ui.position_indicator.setFixedHeight(20) self.client.shutdown()
def main(): def main():
import sys import sys
from qtpy.QtWidgets import QApplication # pylint: disable=ungrouped-imports
app = QApplication(sys.argv) app = QApplication(sys.argv)
icon = QIcon() icon = QIcon()
icon.addFile( icon.addFile(

File diff suppressed because it is too large Load Diff