mirror of
https://github.com/bec-project/bec_widgets.git
synced 2025-12-30 10:41:18 +01:00
feat: add shared selection signal util
This commit is contained in:
@@ -9,7 +9,7 @@ from qtpy.QtWidgets import QListWidget, QListWidgetItem, QWidget
|
||||
|
||||
from bec_widgets.utils.error_popups import SafeSlot
|
||||
from bec_widgets.utils.expandable_frame import ExpandableGroupFrame
|
||||
from bec_widgets.widgets.control.device_manager.components.available_device_resources._util import (
|
||||
from bec_widgets.widgets.control.device_manager.components._util import (
|
||||
SORT_KEY_ROLE,
|
||||
SortableQListWidgetItem,
|
||||
)
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
from typing import Any, Callable, Generator, Iterable, TypeVar
|
||||
|
||||
from PySide6.QtCore import QObject, Signal
|
||||
from qtpy.QtWidgets import QListWidgetItem
|
||||
|
||||
from bec_widgets.widgets.control.device_manager.components.constants import SORT_KEY_ROLE
|
||||
|
||||
_T = TypeVar("_T")
|
||||
_RT = TypeVar("_RT")
|
||||
|
||||
@@ -14,9 +17,6 @@ def yield_only_passing(fn: Callable[[_T], _RT], vals: Iterable[_T]) -> Generator
|
||||
pass
|
||||
|
||||
|
||||
SORT_KEY_ROLE = 117
|
||||
|
||||
|
||||
class SortableQListWidgetItem(QListWidgetItem):
|
||||
"""Store a sorting string key with .setData(SORT_KEY_ROLE, key) to be able to sort a list with \
|
||||
custom widgets and this item."""
|
||||
@@ -34,3 +34,7 @@ class SortableQListWidgetItem(QListWidgetItem):
|
||||
) is None:
|
||||
return False
|
||||
return self_key.lower() < other_key.lower()
|
||||
|
||||
|
||||
class SharedSelectionSignal(QObject):
|
||||
proc = Signal(str)
|
||||
@@ -1,11 +1,14 @@
|
||||
from textwrap import dedent
|
||||
from typing import NamedTuple
|
||||
from uuid import uuid4
|
||||
|
||||
from bec_qthemes import material_icon
|
||||
from qtpy.QtCore import QSize
|
||||
from qtpy.QtCore import QItemSelection, QSize
|
||||
from qtpy.QtWidgets import QFrame, QHBoxLayout, QLabel, QListWidgetItem, QVBoxLayout, QWidget
|
||||
|
||||
from bec_widgets.utils.error_popups import SafeSlot
|
||||
from bec_widgets.utils.expandable_frame import ExpandableGroupFrame
|
||||
from bec_widgets.widgets.control.device_manager.components._util import SharedSelectionSignal
|
||||
from bec_widgets.widgets.control.device_manager.components.available_device_resources.available_device_group_ui import (
|
||||
Ui_AvailableDeviceGroup,
|
||||
)
|
||||
@@ -108,10 +111,21 @@ class _DeviceEntry(NamedTuple):
|
||||
|
||||
class AvailableDeviceGroup(ExpandableGroupFrame, Ui_AvailableDeviceGroup):
|
||||
def __init__(
|
||||
self, parent=None, name: str = "TagGroupTitle", data: set[HashableDevice] = set(), **kwargs
|
||||
self,
|
||||
parent=None,
|
||||
name: str = "TagGroupTitle",
|
||||
data: set[HashableDevice] = set(),
|
||||
shared_selection_signal=SharedSelectionSignal(),
|
||||
**kwargs,
|
||||
):
|
||||
super().__init__(parent=parent, **kwargs)
|
||||
self.setupUi(self)
|
||||
|
||||
self._shared_selection_signal = shared_selection_signal
|
||||
self._shared_selection_uuid = str(uuid4())
|
||||
self._shared_selection_signal.proc.connect(self._handle_shared_selection_signal)
|
||||
self.device_list.selectionModel().selectionChanged.connect(self._on_selection_changed)
|
||||
|
||||
self.title_text = name # type: ignore
|
||||
self._mime_data = []
|
||||
self._devices: dict[str, _DeviceEntry] = {}
|
||||
@@ -165,6 +179,15 @@ class AvailableDeviceGroup(ExpandableGroupFrame, Ui_AvailableDeviceGroup):
|
||||
self.device_list.sizeHintForRow(0) * self.device_list.count() + 50,
|
||||
)
|
||||
|
||||
@SafeSlot(QItemSelection, QItemSelection)
|
||||
def _on_selection_changed(self, selected: QItemSelection, deselected: QItemSelection) -> None:
|
||||
self._shared_selection_signal.proc.emit(self._shared_selection_uuid)
|
||||
|
||||
@SafeSlot(str)
|
||||
def _handle_shared_selection_signal(self, uuid: str):
|
||||
if uuid != self._shared_selection_uuid:
|
||||
self.device_list.clearSelection()
|
||||
|
||||
def resizeEvent(self, event):
|
||||
super().resizeEvent(event)
|
||||
self.setMinimumHeight(self.sizeHint().height())
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
from random import randint
|
||||
from typing import Any, Iterable
|
||||
from uuid import uuid4
|
||||
|
||||
from PySide6.QtCore import QItemSelection
|
||||
from qtpy.QtWidgets import QWidget
|
||||
|
||||
from bec_widgets.utils.bec_widget import BECWidget
|
||||
from bec_widgets.utils.error_popups import SafeSlot
|
||||
from bec_widgets.widgets.control.device_manager.components.available_device_resources._util import (
|
||||
from bec_widgets.widgets.control.device_manager.components._util import (
|
||||
SharedSelectionSignal,
|
||||
yield_only_passing,
|
||||
)
|
||||
from bec_widgets.widgets.control.device_manager.components.available_device_resources.available_device_resources_ui import (
|
||||
@@ -19,10 +22,16 @@ from bec_widgets.widgets.control.device_manager.components.constants import CONF
|
||||
|
||||
|
||||
class AvailableDeviceResources(BECWidget, QWidget, Ui_availableDeviceResources):
|
||||
def __init__(self, parent=None, **kwargs):
|
||||
def __init__(self, parent=None, shared_selection_signal=SharedSelectionSignal(), **kwargs):
|
||||
super().__init__(parent=parent, **kwargs)
|
||||
self.setupUi(self)
|
||||
self._backend = get_backend()
|
||||
self._shared_selection_signal = shared_selection_signal
|
||||
self._shared_selection_uuid = str(uuid4())
|
||||
self._shared_selection_signal.proc.connect(self._handle_shared_selection_signal)
|
||||
self.device_groups_list.selectionModel().selectionChanged.connect(
|
||||
self._on_selection_changed
|
||||
)
|
||||
self.grouping_selector.addItem("deviceTags")
|
||||
self.grouping_selector.addItems(self._backend.allowed_sort_keys)
|
||||
self._grouping_selection_changed("deviceTags")
|
||||
@@ -39,7 +48,12 @@ class AvailableDeviceResources(BECWidget, QWidget, Ui_availableDeviceResources):
|
||||
|
||||
def _add_device_group(self, device_group: str, devices: set[HashableDevice]):
|
||||
item, widget = self.device_groups_list.add_item(
|
||||
device_group, self.device_groups_list, device_group, devices, expanded=False
|
||||
device_group,
|
||||
self.device_groups_list,
|
||||
device_group,
|
||||
devices,
|
||||
shared_selection_signal=self._shared_selection_signal,
|
||||
expanded=False,
|
||||
)
|
||||
item.setData(CONFIG_DATA_ROLE, widget.create_mime_data())
|
||||
|
||||
@@ -57,6 +71,15 @@ class AvailableDeviceResources(BECWidget, QWidget, Ui_availableDeviceResources):
|
||||
for list_item, device_group_widget in self.device_groups_list.item_widget_pairs():
|
||||
list_item.setSizeHint(device_group_widget.sizeHint())
|
||||
|
||||
@SafeSlot(QItemSelection, QItemSelection)
|
||||
def _on_selection_changed(self, selected: QItemSelection, deselected: QItemSelection) -> None:
|
||||
self._shared_selection_signal.proc.emit(self._shared_selection_uuid)
|
||||
|
||||
@SafeSlot(str)
|
||||
def _handle_shared_selection_signal(self, uuid: str):
|
||||
if uuid != self._shared_selection_uuid:
|
||||
self.device_groups_list.clearSelection()
|
||||
|
||||
@SafeSlot(dict)
|
||||
def update_devices_state_name_outside(self, configs: dict):
|
||||
self.update_devices_state([{"name": k, **v} for k, v in configs.items()])
|
||||
|
||||
@@ -27,7 +27,6 @@ from bec_widgets.widgets.control.device_manager.components.constants import (
|
||||
|
||||
|
||||
class _ListOfDeviceGroups(ListOfExpandableFrames[AvailableDeviceGroup]):
|
||||
|
||||
def mimeTypes(self):
|
||||
return [MIME_DEVICE_CONFIG]
|
||||
|
||||
|
||||
@@ -2,4 +2,7 @@ from typing import Final
|
||||
|
||||
# Denotes a MIME type for JSON-encoded list of device config dictionaries
|
||||
MIME_DEVICE_CONFIG: Final[str] = "application/x-bec_device_config"
|
||||
|
||||
# Custom user roles
|
||||
SORT_KEY_ROLE: Final[int] = 117
|
||||
CONFIG_DATA_ROLE: Final[int] = 118
|
||||
|
||||
Reference in New Issue
Block a user