From a4e02460ad05b9466bf7d1f153d6c744b9d79a7e Mon Sep 17 00:00:00 2001 From: David Perl Date: Tue, 2 Sep 2025 21:02:51 +0200 Subject: [PATCH] refactor: util for MimeData --- .../device_manager/components/_util.py | 19 ++++++++++++++++--- .../available_device_group_ui.py | 11 +++-------- .../available_device_resources.py | 8 +++++++- .../available_device_resources_ui.py | 13 +++++-------- 4 files changed, 31 insertions(+), 20 deletions(-) diff --git a/bec_widgets/widgets/control/device_manager/components/_util.py b/bec_widgets/widgets/control/device_manager/components/_util.py index b6cad8d7..fb1f6993 100644 --- a/bec_widgets/widgets/control/device_manager/components/_util.py +++ b/bec_widgets/widgets/control/device_manager/components/_util.py @@ -1,9 +1,14 @@ +import json from typing import Any, Callable, Generator, Iterable, TypeVar -from PySide6.QtCore import QObject, Signal +from bec_lib.utils.json import ExtendedEncoder +from qtpy.QtCore import QByteArray, QMimeData, QObject, Signal # type: ignore from qtpy.QtWidgets import QListWidgetItem -from bec_widgets.widgets.control.device_manager.components.constants import SORT_KEY_ROLE +from bec_widgets.widgets.control.device_manager.components.constants import ( + MIME_DEVICE_CONFIG, + SORT_KEY_ROLE, +) _T = TypeVar("_T") _RT = TypeVar("_RT") @@ -17,8 +22,16 @@ def yield_only_passing(fn: Callable[[_T], _RT], vals: Iterable[_T]) -> Generator pass +def mimedata_from_configs(configs: Iterable[dict]) -> QMimeData: + """Takes an iterable of device configs, gives a QMimeData with the configs json-encoded under the type MIME_DEVICE_CONFIG""" + mime_obj = QMimeData() + byte_array = QByteArray(json.dumps(list(configs), cls=ExtendedEncoder).encode("utf-8")) + mime_obj.setData(MIME_DEVICE_CONFIG, byte_array) + return mime_obj + + class SortableQListWidgetItem(QListWidgetItem): - """Store a sorting string key with .setData(SORT_KEY_ROLE, key) to be able to sort a list with \ + """Store a sorting string key with .setData(SORT_KEY_ROLE, key) to be able to sort a list with custom widgets and this item.""" def __gt__(self, other): diff --git a/bec_widgets/widgets/control/device_manager/components/available_device_resources/available_device_group_ui.py b/bec_widgets/widgets/control/device_manager/components/available_device_resources/available_device_group_ui.py index 88ce0df3..0dafc4d0 100644 --- a/bec_widgets/widgets/control/device_manager/components/available_device_resources/available_device_group_ui.py +++ b/bec_widgets/widgets/control/device_manager/components/available_device_resources/available_device_group_ui.py @@ -1,11 +1,10 @@ -import json from functools import partial -from bec_lib.utils.json import ExtendedEncoder from bec_qthemes import material_icon -from qtpy.QtCore import QByteArray, QMetaObject, QMimeData, Qt +from qtpy.QtCore import QMetaObject, Qt from qtpy.QtWidgets import QLabel, QListWidget, QToolButton, QVBoxLayout +from bec_widgets.widgets.control.device_manager.components._util import mimedata_from_configs from bec_widgets.widgets.control.device_manager.components.constants import ( CONFIG_DATA_ROLE, MIME_DEVICE_CONFIG, @@ -17,11 +16,7 @@ class _DeviceListWiget(QListWidget): return [MIME_DEVICE_CONFIG] def mimeData(self, items): - mime_obj = QMimeData() - data = [item.data(CONFIG_DATA_ROLE) for item in items] - byte_array = QByteArray(json.dumps(data, cls=ExtendedEncoder).encode("utf-8")) - mime_obj.setData(MIME_DEVICE_CONFIG, byte_array) - return mime_obj + return mimedata_from_configs(item.data(CONFIG_DATA_ROLE) for item in items) class Ui_AvailableDeviceGroup(object): diff --git a/bec_widgets/widgets/control/device_manager/components/available_device_resources/available_device_resources.py b/bec_widgets/widgets/control/device_manager/components/available_device_resources/available_device_resources.py index ed754f81..b8ef20f4 100644 --- a/bec_widgets/widgets/control/device_manager/components/available_device_resources/available_device_resources.py +++ b/bec_widgets/widgets/control/device_manager/components/available_device_resources/available_device_resources.py @@ -2,7 +2,7 @@ from random import randint from typing import Any, Iterable from uuid import uuid4 -from PySide6.QtCore import QItemSelection +from qtpy.QtCore import QItemSelection from qtpy.QtWidgets import QWidget from bec_widgets.utils.bec_widget import BECWidget @@ -82,10 +82,16 @@ class AvailableDeviceResources(BECWidget, QWidget, Ui_availableDeviceResources): @SafeSlot(dict) def update_devices_state_name_outside(self, configs: dict): + """Set the display color of individual devices and update the group display + of numbers included. Accepts a dict with the structure {"device_name": config_dict, ...} + as used in server calls.""" self.update_devices_state([{"name": k, **v} for k, v in configs.items()]) @SafeSlot(list) def update_devices_state(self, config_list: list[dict[str, Any]]): + """Set the display color of individual devices and update the group display of numbers + included. Accepts a list of dicts with the complete config as used in + bec_lib.atlas_models.Device.""" self.set_devices_state(yield_only_passing(HashableDevice.model_validate, config_list), True) @SafeSlot(str) diff --git a/bec_widgets/widgets/control/device_manager/components/available_device_resources/available_device_resources_ui.py b/bec_widgets/widgets/control/device_manager/components/available_device_resources/available_device_resources_ui.py index 29217f36..03fa5252 100644 --- a/bec_widgets/widgets/control/device_manager/components/available_device_resources/available_device_resources_ui.py +++ b/bec_widgets/widgets/control/device_manager/components/available_device_resources/available_device_resources_ui.py @@ -1,10 +1,8 @@ from __future__ import annotations import itertools -import json -from bec_lib.utils.json import ExtendedEncoder -from qtpy.QtCore import QByteArray, QMetaObject, QMimeData, Qt +from qtpy.QtCore import QMetaObject, Qt from qtpy.QtWidgets import ( QAbstractItemView, QComboBox, @@ -17,6 +15,7 @@ from qtpy.QtWidgets import ( ) from bec_widgets.utils.list_of_expandable_frames import ListOfExpandableFrames +from bec_widgets.widgets.control.device_manager.components._util import mimedata_from_configs from bec_widgets.widgets.control.device_manager.components.available_device_resources.available_device_group import ( AvailableDeviceGroup, ) @@ -31,11 +30,9 @@ class _ListOfDeviceGroups(ListOfExpandableFrames[AvailableDeviceGroup]): return [MIME_DEVICE_CONFIG] def mimeData(self, items): - mime_obj = QMimeData() - data = list(itertools.chain.from_iterable(item.data(CONFIG_DATA_ROLE) for item in items)) - byte_array = QByteArray(json.dumps(data, cls=ExtendedEncoder).encode("utf-8")) - mime_obj.setData(MIME_DEVICE_CONFIG, byte_array) - return mime_obj + return mimedata_from_configs( + itertools.chain.from_iterable(item.data(CONFIG_DATA_ROLE) for item in items) + ) class Ui_availableDeviceResources(object):