mirror of
https://github.com/bec-project/bec_widgets.git
synced 2026-06-11 07:38:54 +02:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 47351bbde7 | |||
| 397f53b2a1 | |||
| b4a3118e92 |
@@ -9,7 +9,7 @@ from bec_lib.device import ComputedSignal, Device, Positioner, ReadoutPriority
|
||||
from bec_lib.device import Signal as BECSignal
|
||||
from bec_lib.logger import bec_logger
|
||||
from pydantic import Field, field_validator
|
||||
from qtpy.QtCore import QSize, QStringListModel, Signal, Slot
|
||||
from qtpy.QtCore import QSize, QStringListModel, Qt, Signal, Slot
|
||||
from qtpy.QtWidgets import QComboBox, QCompleter, QSizePolicy
|
||||
|
||||
from bec_widgets.utils.bec_connector import ConnectionConfig
|
||||
@@ -191,6 +191,13 @@ class DeviceComboBox(BECWidget, QComboBox):
|
||||
if self.config.autocomplete:
|
||||
self.autocomplete = True
|
||||
|
||||
self._callback_id = self.bec_dispatcher.client.callbacks.register(
|
||||
EventType.DEVICE_UPDATE, self.on_device_update
|
||||
)
|
||||
self.device_config_update.connect(
|
||||
self.update_devices_from_filters, Qt.ConnectionType.QueuedConnection
|
||||
)
|
||||
|
||||
if available_devices is not None:
|
||||
self.set_available_devices(available_devices)
|
||||
|
||||
@@ -216,10 +223,6 @@ class DeviceComboBox(BECWidget, QComboBox):
|
||||
else:
|
||||
self.setCurrentText("")
|
||||
|
||||
self._callback_id = self.bec_dispatcher.client.callbacks.register(
|
||||
EventType.DEVICE_UPDATE, self.on_device_update
|
||||
)
|
||||
self.device_config_update.connect(self.update_devices_from_filters)
|
||||
self.currentTextChanged.connect(self.check_validity)
|
||||
self.check_validity(self.currentText())
|
||||
|
||||
@@ -255,6 +258,9 @@ class DeviceComboBox(BECWidget, QComboBox):
|
||||
@SafeSlot()
|
||||
def update_devices_from_filters(self):
|
||||
"""Refresh the available device list from current device/readout/signal filters."""
|
||||
if self._callback_id is None or getattr(self, "_destroyed", False):
|
||||
return
|
||||
|
||||
self.config.device_filter = [entry.value for entry in self.device_filter]
|
||||
self.config.readout_filter = [entry.value for entry in self.readout_filter]
|
||||
self.config.signal_class_filter = self.signal_class_filter
|
||||
@@ -489,6 +495,8 @@ class DeviceComboBox(BECWidget, QComboBox):
|
||||
action: Device update action emitted by BEC.
|
||||
content: Device update payload. Currently unused.
|
||||
"""
|
||||
if self._callback_id is None or getattr(self, "_destroyed", False):
|
||||
return
|
||||
if action in ["add", "remove", "reload"]:
|
||||
self.device_config_update.emit()
|
||||
|
||||
@@ -496,6 +504,7 @@ class DeviceComboBox(BECWidget, QComboBox):
|
||||
"""Cleanup the widget."""
|
||||
if self._callback_id is not None:
|
||||
self.bec_dispatcher.client.callbacks.remove(self._callback_id)
|
||||
self._callback_id = None
|
||||
super().cleanup()
|
||||
|
||||
def get_current_device(self) -> object:
|
||||
|
||||
@@ -77,6 +77,7 @@ class SignalComboBox(BECWidget, QComboBox):
|
||||
|
||||
device_signal_changed = Signal(str)
|
||||
signal_reset = Signal()
|
||||
device_config_update = Signal()
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
@@ -138,7 +139,10 @@ class SignalComboBox(BECWidget, QComboBox):
|
||||
self.autocomplete = True
|
||||
|
||||
self._device_update_register = self.bec_dispatcher.client.callbacks.register(
|
||||
EventType.DEVICE_UPDATE, self.update_signals_from_filters
|
||||
EventType.DEVICE_UPDATE, self.on_device_update
|
||||
)
|
||||
self.device_config_update.connect(
|
||||
self.update_signals_from_filters, Qt.ConnectionType.QueuedConnection
|
||||
)
|
||||
self.currentTextChanged.connect(self.on_text_changed)
|
||||
|
||||
@@ -207,6 +211,9 @@ class SignalComboBox(BECWidget, QComboBox):
|
||||
content: Optional callback payload from BEC device updates. Currently unused.
|
||||
metadata: Optional callback metadata from BEC device updates. Currently unused.
|
||||
"""
|
||||
if self._device_update_register is None or getattr(self, "_destroyed", False):
|
||||
return
|
||||
|
||||
self.config.signal_filter = [kind.name for kind in self.signal_filter]
|
||||
|
||||
if self._signal_class_filter:
|
||||
@@ -247,6 +254,13 @@ class SignalComboBox(BECWidget, QComboBox):
|
||||
),
|
||||
)
|
||||
|
||||
def on_device_update(self, action: str, content: dict) -> None:
|
||||
"""Refresh filters when BEC reports device configuration changes."""
|
||||
if self._device_update_register is None or getattr(self, "_destroyed", False):
|
||||
return
|
||||
if action in ["add", "remove", "reload"]:
|
||||
self.device_config_update.emit()
|
||||
|
||||
@Property(str)
|
||||
def device(self) -> str:
|
||||
"""Selected device."""
|
||||
@@ -588,7 +602,9 @@ class SignalComboBox(BECWidget, QComboBox):
|
||||
|
||||
def cleanup(self):
|
||||
"""Cleanup the widget."""
|
||||
self.bec_dispatcher.client.callbacks.remove(self._device_update_register)
|
||||
if self._device_update_register is not None:
|
||||
self.bec_dispatcher.client.callbacks.remove(self._device_update_register)
|
||||
self._device_update_register = None
|
||||
super().cleanup()
|
||||
|
||||
@staticmethod
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
from unittest import mock
|
||||
|
||||
import pytest
|
||||
from bec_lib.device import ReadoutPriority
|
||||
|
||||
@@ -124,6 +126,19 @@ def test_device_input_combobox_disabled_invalid_has_neutral_border(device_input_
|
||||
assert "red" in device_input_combobox.styleSheet()
|
||||
|
||||
|
||||
def test_device_input_combobox_cleanup_unregisters_callback(qtbot, mocked_client):
|
||||
with mock.patch.object(mocked_client.callbacks, "remove"):
|
||||
widget = DeviceComboBox(client=mocked_client)
|
||||
qtbot.addWidget(widget)
|
||||
callback_id = widget._callback_id
|
||||
|
||||
widget.close()
|
||||
widget.deleteLater()
|
||||
|
||||
mocked_client.callbacks.remove.assert_called_once_with(callback_id)
|
||||
assert widget._callback_id is None
|
||||
|
||||
|
||||
def test_get_device_from_input_combobox_init(device_input_combobox):
|
||||
device_input_combobox.setCurrentIndex(0)
|
||||
device_text = device_input_combobox.currentText()
|
||||
|
||||
@@ -188,10 +188,12 @@ def test_linked_device_combobox_updates_signal_combobox_on_each_text_change(
|
||||
def test_device_signal_input_base_cleanup(qtbot, mocked_client):
|
||||
with mock.patch.object(mocked_client.callbacks, "remove"):
|
||||
widget = SignalComboBox(client=mocked_client)
|
||||
callback_id = widget._device_update_register
|
||||
widget.close()
|
||||
widget.deleteLater()
|
||||
|
||||
mocked_client.callbacks.remove.assert_called_once_with(widget._device_update_register)
|
||||
mocked_client.callbacks.remove.assert_called_once_with(callback_id)
|
||||
assert widget._device_update_register is None
|
||||
|
||||
|
||||
def test_signal_combobox_get_signal_name_with_item_data(qtbot, device_signal_combobox):
|
||||
|
||||
Reference in New Issue
Block a user