mirror of
https://github.com/bec-project/bec_widgets.git
synced 2025-07-14 11:41:49 +02:00
refactor: base class for motor_control.py widgets
This commit is contained in:
@ -4,4 +4,9 @@ from .scan_control import ScanControl
|
|||||||
from .toolbar import ModularToolBar
|
from .toolbar import ModularToolBar
|
||||||
from .editor import BECEditor
|
from .editor import BECEditor
|
||||||
from .monitor_scatter_2D import BECMonitor2DScatter
|
from .monitor_scatter_2D import BECMonitor2DScatter
|
||||||
from .motor_control import MotorControlRelative, MotorControlAbsolute, MotorControlSelection
|
from .motor_control import (
|
||||||
|
MotorControlRelative,
|
||||||
|
MotorControlAbsolute,
|
||||||
|
MotorControlSelection,
|
||||||
|
MotorThread,
|
||||||
|
)
|
||||||
|
@ -1 +1,6 @@
|
|||||||
from .motor_control import MotorControlRelative, MotorControlAbsolute, MotorControlSelection
|
from .motor_control import (
|
||||||
|
MotorControlRelative,
|
||||||
|
MotorControlAbsolute,
|
||||||
|
MotorControlSelection,
|
||||||
|
MotorThread,
|
||||||
|
)
|
||||||
|
@ -4,7 +4,6 @@ from enum import Enum
|
|||||||
|
|
||||||
import qdarktheme
|
import qdarktheme
|
||||||
|
|
||||||
from pyqtgraph.Qt import uic
|
|
||||||
from qtpy import uic
|
from qtpy import uic
|
||||||
from qtpy.QtCore import QThread, Slot as pyqtSlot
|
from qtpy.QtCore import QThread, Slot as pyqtSlot
|
||||||
from qtpy.QtCore import Signal as pyqtSignal, Qt
|
from qtpy.QtCore import Signal as pyqtSignal, Qt
|
||||||
@ -34,41 +33,24 @@ CONFIG_DEFAULT = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# class MotorControlConnectAbsoltue(QWidget):
|
|
||||||
|
|
||||||
|
class MotorControlWidget(QWidget):
|
||||||
|
"""Base class for motor control widgets."""
|
||||||
|
|
||||||
# class MotorControlPanel(QWidget):
|
def __init__(self, parent=None, client=None, motor_thread=None, config=None):
|
||||||
# def __init__(self,parent=None):
|
super().__init__(parent)
|
||||||
# super().__init__()
|
self.client = client
|
||||||
# self.init_ui()
|
self.motor_thread = motor_thread
|
||||||
# def init_ui(self):
|
|
||||||
# """Initialize the UI."""
|
|
||||||
class MotorControlSelection(QWidget):
|
|
||||||
update_signal = pyqtSignal()
|
|
||||||
selected_motors_signal = pyqtSignal(str, str)
|
|
||||||
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
parent=None,
|
|
||||||
client=None,
|
|
||||||
motor_thread=None,
|
|
||||||
config: dict = None,
|
|
||||||
):
|
|
||||||
super().__init__(parent=parent)
|
|
||||||
|
|
||||||
bec_dispatcher = BECDispatcher()
|
|
||||||
self.client = bec_dispatcher.client if client is None else client
|
|
||||||
self.dev = self.client.device_manager.devices
|
|
||||||
self.config = config
|
self.config = config
|
||||||
|
|
||||||
# Loading UI
|
if not self.client:
|
||||||
current_path = os.path.dirname(__file__)
|
bec_dispatcher = BECDispatcher()
|
||||||
uic.loadUi(os.path.join(current_path, "motor_control_selection.ui"), self)
|
self.client = bec_dispatcher.client
|
||||||
|
|
||||||
# Motor Control Thread
|
if not self.motor_thread:
|
||||||
self.motor_thread = (
|
self.motor_thread = MotorThread(client=self.client)
|
||||||
MotorThread(client=self.client) if motor_thread is None else motor_thread
|
|
||||||
)
|
self._load_ui()
|
||||||
|
|
||||||
if self.config is None:
|
if self.config is None:
|
||||||
print(f"No initial config found for {self.__class__.__name__}")
|
print(f"No initial config found for {self.__class__.__name__}")
|
||||||
@ -76,8 +58,44 @@ class MotorControlSelection(QWidget):
|
|||||||
else:
|
else:
|
||||||
self.on_config_update(self.config)
|
self.on_config_update(self.config)
|
||||||
|
|
||||||
|
def _load_ui(self):
|
||||||
|
"""Load the UI from the .ui file."""
|
||||||
|
|
||||||
|
def _init_ui(self):
|
||||||
|
"""Initialize the UI components specific to the widget."""
|
||||||
|
|
||||||
|
@pyqtSlot(dict)
|
||||||
|
def on_config_update(self, config):
|
||||||
|
"""Handle configuration updates."""
|
||||||
|
self.config = config
|
||||||
|
self._init_ui()
|
||||||
|
|
||||||
|
|
||||||
|
class MotorControlSelection(MotorControlWidget):
|
||||||
|
"""
|
||||||
|
Widget for selecting the motors to control.
|
||||||
|
|
||||||
|
Signals:
|
||||||
|
selected_motors_signal (pyqtSignal): Signal to emit the selected motors.
|
||||||
|
Slots:
|
||||||
|
get_available_motors (pyqtSlot): Slot to populate the available motors in the combo boxes and set the index based on the configuration.
|
||||||
|
select_motor (pyqtSlot): Slot to emit the selected motors.
|
||||||
|
enable_motor_controls (pyqtSlot): Slot to enable/disable the motor controls GUI.
|
||||||
|
"""
|
||||||
|
|
||||||
|
selected_motors_signal = pyqtSignal(str, str)
|
||||||
|
|
||||||
|
def _load_ui(self):
|
||||||
|
"""Load the UI from the .ui file."""
|
||||||
|
current_path = os.path.dirname(__file__)
|
||||||
|
uic.loadUi(os.path.join(current_path, "motor_control_selection.ui"), self)
|
||||||
|
|
||||||
def _init_ui(self):
|
def _init_ui(self):
|
||||||
"""Initialize the UI."""
|
"""Initialize the UI."""
|
||||||
|
# Lock GUI while motors are moving
|
||||||
|
self.motor_thread.lock_gui.connect(self.enable_motor_controls)
|
||||||
|
# self.motor_thread.move_finished.connect(self.motorSelection.setEnabled(True))
|
||||||
|
|
||||||
self.pushButton_connecMotors.clicked.connect(self.select_motor)
|
self.pushButton_connecMotors.clicked.connect(self.select_motor)
|
||||||
self.get_available_motors()
|
self.get_available_motors()
|
||||||
|
|
||||||
@ -98,6 +116,15 @@ class MotorControlSelection(QWidget):
|
|||||||
|
|
||||||
self._init_ui()
|
self._init_ui()
|
||||||
|
|
||||||
|
@pyqtSlot(bool)
|
||||||
|
def enable_motor_controls(self, enable: bool) -> None:
|
||||||
|
"""
|
||||||
|
Enable or disable the motor controls.
|
||||||
|
Args:
|
||||||
|
enable(bool): True to enable, False to disable.
|
||||||
|
"""
|
||||||
|
self.motorSelection.setEnabled(enable)
|
||||||
|
|
||||||
def get_available_motors(self):
|
def get_available_motors(self):
|
||||||
"""
|
"""
|
||||||
Slot to populate the available motors in the combo boxes and set the index based on the configuration.
|
Slot to populate the available motors in the combo boxes and set the index based on the configuration.
|
||||||
@ -110,31 +137,11 @@ class MotorControlSelection(QWidget):
|
|||||||
self.comboBox_motor_y.addItems(self.motor_list)
|
self.comboBox_motor_y.addItems(self.motor_list)
|
||||||
|
|
||||||
# Set the index based on the config if provided
|
# Set the index based on the config if provided
|
||||||
if self.config is not None:
|
if self.config:
|
||||||
index_x = self.comboBox_motor_x.findText(self.motor_x)
|
index_x = self.comboBox_motor_x.findText(self.motor_x)
|
||||||
index_y = self.comboBox_motor_y.findText(self.motor_y)
|
index_y = self.comboBox_motor_y.findText(self.motor_y)
|
||||||
|
self.comboBox_motor_x.setCurrentIndex(index_x if index_x != -1 else 0)
|
||||||
if index_x != -1:
|
self.comboBox_motor_y.setCurrentIndex(index_y if index_y != -1 else 0)
|
||||||
self.comboBox_motor_x.setCurrentIndex(index_x)
|
|
||||||
else:
|
|
||||||
print(
|
|
||||||
f"Warning: Motor '{self.motor_x}' specified in the config file is not available."
|
|
||||||
)
|
|
||||||
self.comboBox_motor_x.setCurrentIndex(0)
|
|
||||||
|
|
||||||
if index_y != -1:
|
|
||||||
self.comboBox_motor_y.setCurrentIndex(index_y)
|
|
||||||
else:
|
|
||||||
print(
|
|
||||||
f"Warning: Motor '{self.motor_y}' specified in the config file is not available."
|
|
||||||
)
|
|
||||||
self.comboBox_motor_y.setCurrentIndex(0)
|
|
||||||
if index_x != -1 and index_y != -1:
|
|
||||||
self.selected_motors_signal.emit(self.motor_x, self.motor_y)
|
|
||||||
# setup default index 0, if there is no config
|
|
||||||
else:
|
|
||||||
self.comboBox_motor_x.setCurrentIndex(0)
|
|
||||||
self.comboBox_motor_y.setCurrentIndex(0)
|
|
||||||
|
|
||||||
def select_motor(self):
|
def select_motor(self):
|
||||||
"""Emit the selected motors"""
|
"""Emit the selected motors"""
|
||||||
@ -142,41 +149,53 @@ class MotorControlSelection(QWidget):
|
|||||||
motor_y = self.comboBox_motor_y.currentText()
|
motor_y = self.comboBox_motor_y.currentText()
|
||||||
|
|
||||||
self.selected_motors_signal.emit(motor_x, motor_y)
|
self.selected_motors_signal.emit(motor_x, motor_y)
|
||||||
print(f"emitted motors {motor_x} and {motor_y}")
|
|
||||||
|
|
||||||
|
|
||||||
class MotorControlAbsolute(QWidget):
|
class MotorControlAbsolute(MotorControlWidget):
|
||||||
update_signal = pyqtSignal()
|
"""
|
||||||
|
Widget for controlling the motors to absolute coordinates.
|
||||||
|
|
||||||
|
Signals:
|
||||||
|
coordinates_signal (pyqtSignal): Signal to emit the coordinates.
|
||||||
|
Slots:
|
||||||
|
change_motors (pyqtSlot): Slot to change the active motors.
|
||||||
|
enable_motor_controls (pyqtSlot): Slot to enable/disable the motor controls.
|
||||||
|
"""
|
||||||
|
|
||||||
coordinates_signal = pyqtSignal(tuple)
|
coordinates_signal = pyqtSignal(tuple)
|
||||||
|
|
||||||
def __init__(
|
def _load_ui(self):
|
||||||
self,
|
"""Load the UI from the .ui file."""
|
||||||
parent=None,
|
|
||||||
client=None,
|
|
||||||
motor_thread=None,
|
|
||||||
config: dict = None,
|
|
||||||
):
|
|
||||||
super().__init__(parent=parent)
|
|
||||||
|
|
||||||
bec_dispatcher = BECDispatcher()
|
|
||||||
self.client = bec_dispatcher.client if client is None else client
|
|
||||||
self.dev = self.client.device_manager.devices
|
|
||||||
self.config = config
|
|
||||||
|
|
||||||
# Loading UI
|
|
||||||
current_path = os.path.dirname(__file__)
|
current_path = os.path.dirname(__file__)
|
||||||
uic.loadUi(os.path.join(current_path, "motor_control_absolute.ui"), self)
|
uic.loadUi(os.path.join(current_path, "motor_control_absolute.ui"), self)
|
||||||
|
|
||||||
# Motor Control Thread
|
def _init_ui(self):
|
||||||
self.motor_thread = (
|
"""Initialize the UI."""
|
||||||
MotorThread(client=self.client) if motor_thread is None else motor_thread
|
|
||||||
|
# Check if there are any motors connected
|
||||||
|
if self.motor_x is None or self.motor_y is None:
|
||||||
|
self.motorControl_absolute.setEnabled(False)
|
||||||
|
return
|
||||||
|
|
||||||
|
# Move to absolute coordinates
|
||||||
|
self.pushButton_go_absolute.clicked.connect(
|
||||||
|
lambda: self.move_motor_absolute(
|
||||||
|
self.spinBox_absolute_x.value(), self.spinBox_absolute_y.value()
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
if self.config is None:
|
self.pushButton_set.clicked.connect(self.save_absolute_coordinates)
|
||||||
print(f"No initial config found for {self.__class__.__name__}")
|
self.pushButton_save.clicked.connect(self.save_current_coordinates)
|
||||||
self._init_ui()
|
self.pushButton_stop.clicked.connect(self.motor_thread.stop_movement)
|
||||||
else:
|
|
||||||
self.on_config_update(self.config)
|
# Enable/Disable GUI
|
||||||
|
self.motor_thread.lock_gui.connect(self.enable_motor_controls)
|
||||||
|
# self.motor_thread.move_finished.connect(lambda: self._enable_motor_controls(True))
|
||||||
|
|
||||||
|
# Error messages
|
||||||
|
self.motor_thread.motor_error.connect(
|
||||||
|
lambda error: MotorControlErrors.display_error_message(error)
|
||||||
|
)
|
||||||
|
|
||||||
@pyqtSlot(dict)
|
@pyqtSlot(dict)
|
||||||
def on_config_update(self, config: dict) -> None:
|
def on_config_update(self, config: dict) -> None:
|
||||||
@ -194,51 +213,50 @@ class MotorControlAbsolute(QWidget):
|
|||||||
|
|
||||||
self._init_ui()
|
self._init_ui()
|
||||||
|
|
||||||
def _init_ui(self):
|
@pyqtSlot(bool)
|
||||||
"""Initialize the UI."""
|
def enable_motor_controls(self, enable: bool) -> None:
|
||||||
|
"""
|
||||||
|
Enable or disable the motor controls.
|
||||||
|
Args:
|
||||||
|
enable(bool): True to enable, False to disable.
|
||||||
|
"""
|
||||||
|
|
||||||
# Check if there are any motors connected
|
|
||||||
if (
|
|
||||||
self.motor_x is None or self.motor_y is None
|
|
||||||
): # TODO change logic of checking -> jsut check names
|
|
||||||
self.motorControl_absolute.setEnabled(False)
|
|
||||||
return
|
|
||||||
|
|
||||||
# Move to absolute coordinates
|
|
||||||
self.pushButton_go_absolute.clicked.connect(
|
|
||||||
lambda: self.move_motor_absolute(
|
|
||||||
self.spinBox_absolute_x.value(), self.spinBox_absolute_y.value()
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
self.pushButton_set.clicked.connect(self.save_absolute_coordinates)
|
|
||||||
self.pushButton_save.clicked.connect(self.save_current_coordinates)
|
|
||||||
self.pushButton_stop.clicked.connect(self.motor_thread.stop_movement)
|
|
||||||
|
|
||||||
# Enable/Disable GUI
|
|
||||||
self.motor_thread.move_finished.connect(lambda: self._enable_motor_controls(True))
|
|
||||||
|
|
||||||
# Error messages
|
|
||||||
self.motor_thread.motor_error.connect(
|
|
||||||
lambda error: MotorControlErrors.display_error_message(error)
|
|
||||||
)
|
|
||||||
|
|
||||||
def _enable_motor_controls(self, disable: bool) -> None:
|
|
||||||
# Disable or enable all controls within the motorControl_absolute group box
|
# Disable or enable all controls within the motorControl_absolute group box
|
||||||
for widget in self.motorControl_absolute.findChildren(QWidget):
|
for widget in self.motorControl_absolute.findChildren(QWidget):
|
||||||
widget.setEnabled(disable)
|
widget.setEnabled(enable)
|
||||||
|
|
||||||
# Enable the pushButton_stop if the motor is moving
|
# Enable the pushButton_stop if the motor is moving
|
||||||
self.pushButton_stop.setEnabled(True)
|
self.pushButton_stop.setEnabled(True)
|
||||||
|
|
||||||
|
@pyqtSlot(str, str)
|
||||||
|
def change_motors(self, motor_x: str, motor_y: str):
|
||||||
|
"""
|
||||||
|
Change the active motors and update config.
|
||||||
|
Can be connected to the selected_motors_signal from MotorControlSelection.
|
||||||
|
Args:
|
||||||
|
motor_x(str): New motor X to be controlled.
|
||||||
|
motor_y(str): New motor Y to be controlled.
|
||||||
|
"""
|
||||||
|
self.motor_x = motor_x
|
||||||
|
self.motor_y = motor_y
|
||||||
|
self.config["motor_control"]["motor_x"] = motor_x
|
||||||
|
self.config["motor_control"]["motor_y"] = motor_y
|
||||||
|
|
||||||
def move_motor_absolute(self, x: float, y: float) -> None:
|
def move_motor_absolute(self, x: float, y: float) -> None:
|
||||||
self._enable_motor_controls(False)
|
"""
|
||||||
|
Move the motor to the target coordinates.
|
||||||
|
Args:
|
||||||
|
x(float): Target x coordinate.
|
||||||
|
y(float): Target y coordinate.
|
||||||
|
"""
|
||||||
|
# self._enable_motor_controls(False)
|
||||||
target_coordinates = (x, y)
|
target_coordinates = (x, y)
|
||||||
self.motor_thread.move_absolute(self.motor_x, self.motor_y, target_coordinates)
|
self.motor_thread.move_absolute(self.motor_x, self.motor_y, target_coordinates)
|
||||||
if self.checkBox_save_with_go.isChecked():
|
if self.checkBox_save_with_go.isChecked():
|
||||||
self.save_absolute_coordinates()
|
self.save_absolute_coordinates()
|
||||||
|
|
||||||
def _init_keyboard_shortcuts(self):
|
def _init_keyboard_shortcuts(self):
|
||||||
|
"""Initialize the keyboard shortcuts."""
|
||||||
# Go absolute button
|
# Go absolute button
|
||||||
self.pushButton_go_absolute.setShortcut("Ctrl+G")
|
self.pushButton_go_absolute.setShortcut("Ctrl+G")
|
||||||
self.pushButton_go_absolute.setToolTip("Ctrl+G")
|
self.pushButton_go_absolute.setToolTip("Ctrl+G")
|
||||||
@ -265,43 +283,27 @@ class MotorControlAbsolute(QWidget):
|
|||||||
|
|
||||||
def save_current_coordinates(self):
|
def save_current_coordinates(self):
|
||||||
"""Emit the current coordinates from the motor thread"""
|
"""Emit the current coordinates from the motor thread"""
|
||||||
x, y = self.motor_thread.retrieve_coordinates()
|
x, y = self.motor_thread.get_coordinates(self.motor_x, self.motor_y)
|
||||||
self.coordinates_signal.emit((x, y))
|
self.coordinates_signal.emit((round(x, self.precision), round(y, self.precision)))
|
||||||
|
|
||||||
|
|
||||||
class MotorControlRelative(QWidget):
|
class MotorControlRelative(MotorControlWidget):
|
||||||
update_signal = pyqtSignal()
|
"""
|
||||||
|
Widget for controlling the motors to relative coordinates.
|
||||||
|
|
||||||
def __init__(
|
Signals:
|
||||||
self,
|
coordinates_signal (pyqtSignal): Signal to emit the coordinates.
|
||||||
parent=None,
|
Slots:
|
||||||
client=None,
|
change_motors (pyqtSlot): Slot to change the active motors.
|
||||||
motor_thread=None,
|
enable_motor_controls (pyqtSlot): Slot to enable/disable the motor controls.
|
||||||
config: dict = None,
|
"""
|
||||||
):
|
|
||||||
super().__init__(parent=parent)
|
|
||||||
|
|
||||||
# BECclient
|
|
||||||
bec_dispatcher = BECDispatcher()
|
|
||||||
self.client = bec_dispatcher.client if client is None else client
|
|
||||||
self.dev = self.client.device_manager.devices
|
|
||||||
self.config = config
|
|
||||||
|
|
||||||
|
def _load_ui(self):
|
||||||
|
"""Load the UI from the .ui file."""
|
||||||
# Loading UI
|
# Loading UI
|
||||||
current_path = os.path.dirname(__file__)
|
current_path = os.path.dirname(__file__)
|
||||||
uic.loadUi(os.path.join(current_path, "motor_control_relative.ui"), self)
|
uic.loadUi(os.path.join(current_path, "motor_control_relative.ui"), self)
|
||||||
|
|
||||||
# Motor Control Thread
|
|
||||||
self.motor_thread = (
|
|
||||||
MotorThread(client=self.client) if motor_thread is None else motor_thread
|
|
||||||
)
|
|
||||||
|
|
||||||
self._init_ui()
|
|
||||||
if self.config is None:
|
|
||||||
print(f"No initial config found for {self.__class__.__name__}")
|
|
||||||
else:
|
|
||||||
self.on_config_update(self.config)
|
|
||||||
|
|
||||||
def _init_ui(self):
|
def _init_ui(self):
|
||||||
"""Initialize the UI."""
|
"""Initialize the UI."""
|
||||||
self._init_ui_motor_control()
|
self._init_ui_motor_control()
|
||||||
@ -330,6 +332,8 @@ class MotorControlRelative(QWidget):
|
|||||||
self.checkBox_same_xy.setChecked(self.config["motor_control"]["step_x_y_same"])
|
self.checkBox_same_xy.setChecked(self.config["motor_control"]["step_x_y_same"])
|
||||||
self.checkBox_enableArrows.setChecked(self.config["motor_control"]["move_with_arrows"])
|
self.checkBox_enableArrows.setChecked(self.config["motor_control"]["move_with_arrows"])
|
||||||
|
|
||||||
|
self._init_ui()
|
||||||
|
|
||||||
def _init_ui_motor_control(self) -> None:
|
def _init_ui_motor_control(self) -> None:
|
||||||
"""Initialize the motor control elements"""
|
"""Initialize the motor control elements"""
|
||||||
|
|
||||||
@ -354,7 +358,7 @@ class MotorControlRelative(QWidget):
|
|||||||
self._update_arrow_key_shortcuts()
|
self._update_arrow_key_shortcuts()
|
||||||
|
|
||||||
# Enable/Disable GUI
|
# Enable/Disable GUI
|
||||||
self.motor_thread.move_finished.connect(lambda: self.enable_motor_controls(True))
|
self.motor_thread.lock_gui.connect(self.enable_motor_controls)
|
||||||
|
|
||||||
# Precision update
|
# Precision update
|
||||||
self.spinBox_precision.valueChanged.connect(lambda x: self._update_precision(x))
|
self.spinBox_precision.valueChanged.connect(lambda x: self._update_precision(x))
|
||||||
@ -440,15 +444,11 @@ class MotorControlRelative(QWidget):
|
|||||||
value = self.spinBox_step_y.value()
|
value = self.spinBox_step_y.value()
|
||||||
self.spinBox_step_x.setValue(value)
|
self.spinBox_step_x.setValue(value)
|
||||||
|
|
||||||
@pyqtSlot()
|
|
||||||
def enable_motor_control(self):
|
|
||||||
"""Enable the motor control buttons."""
|
|
||||||
self.motorControl.setEnabled(True)
|
|
||||||
|
|
||||||
@pyqtSlot(str, str)
|
@pyqtSlot(str, str)
|
||||||
def change_motors(self, motor_x: str, motor_y: str):
|
def change_motors(self, motor_x: str, motor_y: str):
|
||||||
"""
|
"""
|
||||||
Change the active motors and update config.
|
Change the active motors and update config.
|
||||||
|
Can be connected to the selected_motors_signal from MotorControlSelection.
|
||||||
Args:
|
Args:
|
||||||
motor_x(str): New motor X to be controlled.
|
motor_x(str): New motor X to be controlled.
|
||||||
motor_y(str): New motor Y to be controlled.
|
motor_y(str): New motor Y to be controlled.
|
||||||
@ -458,11 +458,12 @@ class MotorControlRelative(QWidget):
|
|||||||
self.config["motor_control"]["motor_x"] = motor_x
|
self.config["motor_control"]["motor_x"] = motor_x
|
||||||
self.config["motor_control"]["motor_y"] = motor_y
|
self.config["motor_control"]["motor_y"] = motor_y
|
||||||
|
|
||||||
|
@pyqtSlot(bool)
|
||||||
def enable_motor_controls(self, disable: bool) -> None:
|
def enable_motor_controls(self, disable: bool) -> None:
|
||||||
"""
|
"""
|
||||||
Enable or disable the motor controls.
|
Enable or disable the motor controls.
|
||||||
Args:
|
Args:
|
||||||
disable(bool): True to disable, False to enable.
|
enable(bool): True to disable, False to enable.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Disable or enable all controls within the motorControl_absolute group box
|
# Disable or enable all controls within the motorControl_absolute group box
|
||||||
@ -480,7 +481,6 @@ class MotorControlRelative(QWidget):
|
|||||||
axis(str): Axis to move.
|
axis(str): Axis to move.
|
||||||
direction(int): Direction to move. 1 for positive, -1 for negative.
|
direction(int): Direction to move. 1 for positive, -1 for negative.
|
||||||
"""
|
"""
|
||||||
self.enable_motor_controls(False)
|
|
||||||
if axis == "x":
|
if axis == "x":
|
||||||
step = direction * self.spinBox_step_x.value()
|
step = direction * self.spinBox_step_x.value()
|
||||||
elif axis == "y":
|
elif axis == "y":
|
||||||
@ -489,6 +489,8 @@ class MotorControlRelative(QWidget):
|
|||||||
|
|
||||||
|
|
||||||
class MotorControlErrors:
|
class MotorControlErrors:
|
||||||
|
"""Class for displaying formatted error messages."""
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def display_error_message(error_message: str) -> None:
|
def display_error_message(error_message: str) -> None:
|
||||||
"""
|
"""
|
||||||
@ -543,24 +545,15 @@ class MotorThread(QThread):
|
|||||||
"""
|
"""
|
||||||
QThread subclass for controlling motor actions asynchronously.
|
QThread subclass for controlling motor actions asynchronously.
|
||||||
|
|
||||||
Attributes:
|
Signals:
|
||||||
coordinates_updated (pyqtSignal): Signal to emit current coordinates.
|
coordinates_updated (pyqtSignal): Signal to emit current coordinates.
|
||||||
limits_retrieved (pyqtSignal): Signal to emit current limits.
|
motor_error (pyqtSignal): Signal to emit when there is an error with the motors.
|
||||||
move_finished (pyqtSignal): Signal to emit when the move is finished.
|
lock_gui (pyqtSignal): Signal to lock/unlock the GUI.
|
||||||
motors_loaded (pyqtSignal): Signal to emit when the motors are loaded.
|
|
||||||
motors_selected (pyqtSignal): Signal to emit when the motors are selected.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
coordinates_updated = pyqtSignal(float, float) # Signal to emit current coordinates
|
coordinates_updated = pyqtSignal(float, float) # Signal to emit current coordinates
|
||||||
limits_retrieved = pyqtSignal(list, list) # Signal to emit current limits #TODO remove?
|
|
||||||
move_finished = pyqtSignal() # Signal to emit when the move is finished
|
|
||||||
motors_loaded = pyqtSignal(
|
|
||||||
list, list
|
|
||||||
) # Signal to emit when the motors are loaded #todo remove?
|
|
||||||
motors_selected = pyqtSignal(
|
|
||||||
object, object
|
|
||||||
) # Signal to emit when the motors are selected #TODO remove?
|
|
||||||
motor_error = pyqtSignal(str) # Signal to emit when there is an error with the motors
|
motor_error = pyqtSignal(str) # Signal to emit when there is an error with the motors
|
||||||
|
lock_gui = pyqtSignal(bool) # Signal to lock/unlock the GUI
|
||||||
|
|
||||||
def __init__(self, parent=None, client=None):
|
def __init__(self, parent=None, client=None):
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
@ -648,6 +641,7 @@ class MotorThread(QThread):
|
|||||||
motor_y(str): Motor Y to move.
|
motor_y(str): Motor Y to move.
|
||||||
target_coordinates(tuple): Target coordinates.
|
target_coordinates(tuple): Target coordinates.
|
||||||
"""
|
"""
|
||||||
|
self.lock_gui.emit(False)
|
||||||
try:
|
try:
|
||||||
status = self.scans.mv(
|
status = self.scans.mv(
|
||||||
self.dev[motor_x],
|
self.dev[motor_x],
|
||||||
@ -660,7 +654,7 @@ class MotorThread(QThread):
|
|||||||
except AlarmBase as e:
|
except AlarmBase as e:
|
||||||
self.motor_error.emit(str(e))
|
self.motor_error.emit(str(e))
|
||||||
finally:
|
finally:
|
||||||
self.move_finished.emit()
|
self.lock_gui.emit(True)
|
||||||
|
|
||||||
def _move_motor_relative(self, motor, value: float) -> None:
|
def _move_motor_relative(self, motor, value: float) -> None:
|
||||||
"""
|
"""
|
||||||
@ -669,31 +663,15 @@ class MotorThread(QThread):
|
|||||||
motor(str): Motor to move.
|
motor(str): Motor to move.
|
||||||
value(float): Value to move.
|
value(float): Value to move.
|
||||||
"""
|
"""
|
||||||
|
self.lock_gui.emit(False)
|
||||||
try:
|
try:
|
||||||
status = self.scans.mv(self.dev[motor], value, relative=True)
|
status = self.scans.mv(self.dev[motor], value, relative=True)
|
||||||
status.wait()
|
status.wait()
|
||||||
except AlarmBase as e:
|
except AlarmBase as e:
|
||||||
print(e)
|
|
||||||
self.motor_error.emit(str(e))
|
self.motor_error.emit(str(e))
|
||||||
finally:
|
finally:
|
||||||
self.move_finished.emit()
|
self.lock_gui.emit(True)
|
||||||
|
|
||||||
def stop_movement(self):
|
def stop_movement(self):
|
||||||
self.queue.request_scan_abortion()
|
self.queue.request_scan_abortion()
|
||||||
self.queue.request_queue_reset()
|
self.queue.request_queue_reset()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
bec_dispatcher = BECDispatcher()
|
|
||||||
# BECclient global variables
|
|
||||||
client = bec_dispatcher.client
|
|
||||||
client.start()
|
|
||||||
|
|
||||||
app = QApplication([])
|
|
||||||
qdarktheme.setup_theme("auto")
|
|
||||||
# motor_control = MotorControlRelative(client=client, config=CONFIG_DEFAULT)
|
|
||||||
|
|
||||||
motor_control = MotorControlSelection(client=client, config=CONFIG_DEFAULT)
|
|
||||||
window = motor_control
|
|
||||||
window.show()
|
|
||||||
app.exec()
|
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>Form</string>
|
<string>Motor Control Selection</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
<item>
|
<item>
|
||||||
|
Reference in New Issue
Block a user