mirror of
https://github.com/bec-project/bec_widgets.git
synced 2026-06-05 04:48:40 +02:00
wip: interlock gui
This commit is contained in:
@@ -0,0 +1,170 @@
|
||||
from bec_lib.builtin_actor_hli import ScanInterlockHli
|
||||
from bec_lib.endpoints import MessageEndpoints
|
||||
from bec_lib.messages import BlStateStatus
|
||||
from qtpy import QtGui, QtWidgets
|
||||
from qtpy.QtCore import Qt
|
||||
|
||||
from bec_widgets.utils.bec_widget import BECWidget, ConnectionConfig
|
||||
from bec_widgets.utils.error_popups import SafeSlot
|
||||
from bec_widgets.widgets.utility.toggle.toggle import ToggleSwitch
|
||||
|
||||
|
||||
class ScanInterlockToggle(ToggleSwitch):
|
||||
def __init__(self, interlock: ScanInterlockHli, parent):
|
||||
super().__init__(parent=parent)
|
||||
self._interlock = interlock
|
||||
|
||||
def mousePressEvent(self, event):
|
||||
if self.isEnabled() and event.button() == Qt.MouseButton.LeftButton:
|
||||
self._interlock.enabled = not self.checked
|
||||
|
||||
|
||||
class BlStateList(QtWidgets.QListWidget):
|
||||
def __init__(self, interlock: ScanInterlockHli, parent):
|
||||
super().__init__(parent)
|
||||
self._interlock = interlock
|
||||
|
||||
def dropEvent(self, event: QtGui.QDropEvent, /) -> None:
|
||||
data = event.mimeData()
|
||||
if not data.hasText():
|
||||
return
|
||||
self._interlock.add_state_to_interlock(data.text(), "valid")
|
||||
|
||||
|
||||
class ScanInterlockControl(BECWidget, QtWidgets.QWidget):
|
||||
"""
|
||||
ScanInterlockControl can be used to enable/disable the scan interlock actor,
|
||||
and add/remove beamline states for it to watch.
|
||||
"""
|
||||
|
||||
RPC = False
|
||||
PLUGIN = True
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
parent: QtWidgets.QWidget | None = None,
|
||||
client=None,
|
||||
config: ConnectionConfig | None = None,
|
||||
gui_id: str | None = None,
|
||||
theme_update: bool = False,
|
||||
**kwargs,
|
||||
):
|
||||
"""
|
||||
Args:
|
||||
parent (QtWidgets.QWidget, optional): The parent widget.
|
||||
client: The BEC client.
|
||||
config (ConnectionConfig, optional): The connection configuration.
|
||||
gui_id (str, optional): The GUI ID.
|
||||
theme_update (bool, optional): Whether to subscribe to theme updates. Defaults to False.
|
||||
"""
|
||||
super().__init__(
|
||||
parent=parent,
|
||||
client=client,
|
||||
config=config,
|
||||
gui_id=gui_id,
|
||||
theme_update=theme_update,
|
||||
**kwargs,
|
||||
)
|
||||
self._interlock = self.client.builtin_actors.scan_interlock
|
||||
self._layout = QtWidgets.QVBoxLayout(self)
|
||||
self._setup_control_layout()
|
||||
self._setup_list_layout()
|
||||
self.bec_dispatcher.connect_slot(
|
||||
self._update_all_content,
|
||||
MessageEndpoints.builtin_actor_update_notif("ScanInterlockActor"),
|
||||
)
|
||||
self._update_all_content()
|
||||
|
||||
def _setup_control_layout(self):
|
||||
self._controls_layout = QtWidgets.QHBoxLayout()
|
||||
self._layout.addLayout(self._controls_layout)
|
||||
self._enabled_text = QtWidgets.QLabel()
|
||||
self._enabled_text.setText("Widget Uninitialised")
|
||||
self._enabled_toggle = ScanInterlockToggle(self._interlock, parent=self)
|
||||
self._controls_layout.addWidget(self._enabled_text)
|
||||
self._controls_layout.addWidget(self._enabled_toggle)
|
||||
self._enabled_toggle
|
||||
|
||||
def _set_enabled_text(self, enabled: bool):
|
||||
self._enabled_text.setText(
|
||||
"Scan Interlock Enabled" if enabled else "Scan Interlock Disabled"
|
||||
)
|
||||
|
||||
def _setup_list_layout(self):
|
||||
self._list_layout = QtWidgets.QVBoxLayout()
|
||||
self._layout.addLayout(self._list_layout)
|
||||
self._list_layout.addWidget(QtWidgets.QLabel("Beamline states watched:"))
|
||||
self._bl_states_list = BlStateList(self._interlock, self)
|
||||
self._bl_states_list.setDragDropMode(QtWidgets.QListWidget.DragDropMode.DropOnly)
|
||||
self._list_layout.addWidget(self._bl_states_list)
|
||||
|
||||
self._delete_button_layout = QtWidgets.QHBoxLayout()
|
||||
self._list_layout.addLayout(self._delete_button_layout)
|
||||
|
||||
self._delete_button = QtWidgets.QPushButton("Remove selected states from interlock")
|
||||
self._delete_button_layout.addWidget(self._delete_button)
|
||||
self._delete_button.clicked.connect(self._delete_selected)
|
||||
|
||||
self._delete_all_button = QtWidgets.QPushButton("Remove all states")
|
||||
self._delete_button_layout.addWidget(self._delete_all_button)
|
||||
self._delete_all_button.clicked.connect(self._delete_all)
|
||||
|
||||
@SafeSlot()
|
||||
def _delete_selected(self):
|
||||
to_delete = [i.text() for i in self._bl_states_list.selectedItems()]
|
||||
for state in to_delete:
|
||||
self._interlock.remove_state_from_interlock(state)
|
||||
|
||||
@SafeSlot()
|
||||
def _delete_all(self):
|
||||
self._interlock.clear_all()
|
||||
|
||||
def _update_list(self, list_content: dict[str, BlStateStatus]):
|
||||
self._bl_states_list.clear()
|
||||
for item in list_content:
|
||||
self._bl_states_list.addItem(item)
|
||||
|
||||
@SafeSlot()
|
||||
def _update_all_content(self, *_, **__):
|
||||
self._set_enabled_text(self._interlock.enabled)
|
||||
self._enabled_toggle.setChecked(self._interlock.enabled)
|
||||
self._update_list(self._interlock.states_watched)
|
||||
|
||||
|
||||
if __name__ == "__main__": # pragma: no cover
|
||||
# pylint: disable=import-outside-toplevel
|
||||
|
||||
from qtpy.QtWidgets import QApplication
|
||||
|
||||
from bec_widgets.widgets.utility.visual.dark_mode_button.dark_mode_button import DarkModeButton
|
||||
|
||||
app = QApplication([])
|
||||
main_window = QtWidgets.QMainWindow()
|
||||
|
||||
central_widget = QtWidgets.QWidget()
|
||||
button = DarkModeButton()
|
||||
layout = QtWidgets.QVBoxLayout(central_widget)
|
||||
main_window.setCentralWidget(central_widget)
|
||||
scan_interlock_control = ScanInterlockControl() # type: ignore
|
||||
layout.addWidget(button)
|
||||
layout.addWidget(scan_interlock_control)
|
||||
|
||||
class TestList(QtWidgets.QListWidget):
|
||||
def mimeData(self, items, /):
|
||||
mimedata = super().mimeData(items)
|
||||
text = ",".join([i.text() for i in items])
|
||||
mimedata.setText(text)
|
||||
return mimedata
|
||||
|
||||
test_list = TestList()
|
||||
test_list.addItems(["samx_in_limits", "samy_in_limits"])
|
||||
test_list.setDragEnabled(True)
|
||||
|
||||
layout.addWidget(test_list)
|
||||
lineedit = QtWidgets.QLineEdit()
|
||||
lineedit.setDragEnabled(True)
|
||||
layout.addWidget(lineedit)
|
||||
main_window.setWindowTitle("Scan Interlock Control")
|
||||
main_window.resize(800, 400)
|
||||
main_window.show()
|
||||
app.exec_()
|
||||
Reference in New Issue
Block a user