# -*- coding: utf-8 -*- """Collection of additional helper utilities for dialog management.""" __all__ = ['WidgetGroup'] import typing from qtpy import QtWidgets if typing.TYPE_CHECKING: import typing_extensions class WidgetGroup(typing.Sequence[QtWidgets.QWidget]): """Collection of widgets, with ability for synchronous control.""" __slots__ = ('__content',) def __init__(self, *args: typing.Union[QtWidgets.QWidget, typing.Iterable[QtWidgets.QWidget]]) -> None: """Initialize new :class:`~WidgetGroup` instance.""" self.__content: 'typing_extensions.Final[typing.List[QtWidgets.QWidget]]' = [] arg: typing.Union[QtWidgets.QWidget, typing.Iterable[QtWidgets.QWidget]] for arg in args: if isinstance(arg, QtWidgets.QWidget): self.__content.append(arg) else: self.__content.extend(arg) def disable(self, state: bool = True) -> None: """Set disabled state to all widgets in the group.""" self.for_each(action=lambda item: item.setDisabled(state)) def enable(self, state: bool = True) -> None: """Set enabled state to all widgets in the group.""" self.for_each(action=lambda item: item.setEnabled(state)) def for_each(self, action: typing.Callable[[QtWidgets.QWidget], typing.Any]) -> None: """Preform same `action` for each widget in the group.""" item: 'QtWidgets.QWidget' for item in self.__content: action(item) def hide(self, state: bool = True) -> None: """Set hidden state to all widgets in the group.""" self.for_each(action=lambda item: item.setHidden(state)) def only(self, predicate: typing.Callable[[QtWidgets.QWidget], bool]) -> 'WidgetGroup': """Filter widgets in group by predicate.""" return WidgetGroup( item for item in self.__content if predicate(item) ) def only_disabled(self) -> 'WidgetGroup': """Select widgets that are disabled.""" return self.only(predicate=lambda item: not item.isEnabled()) def only_enabled(self) -> 'WidgetGroup': """Select widgets that are enabled.""" return self.only(predicate=lambda item: item.isEnabled()) def only_hidden(self) -> 'WidgetGroup': """Select widgets that are hidden.""" return self.only(predicate=lambda item: not item.isVisible()) def only_visible(self) -> 'WidgetGroup': """Select widgets that are visible.""" return self.only(predicate=lambda item: item.isVisible()) def show(self, state: bool = True) -> None: """Set visible state to all widgets in cgroup.""" self.for_each(action=lambda item: item.setVisible(state)) def __add__(self, other: 'WidgetGroup') -> 'WidgetGroup': """Concatenate two widget groups.""" if not isinstance(other, WidgetGroup): return NotImplemented # type: ignore return WidgetGroup(self, other) @typing.overload def __getitem__(self, index: int) -> 'QtWidgets.QWidget': """Retrieve single widget by its index.""" @typing.overload def __getitem__(self, index: slice) -> 'WidgetGroup': """Retrieve subset of widgets.""" def __getitem__(self, index: typing.Union[int, slice]) -> typing.Union['QtWidgets.QWidget', 'WidgetGroup']: """Retrieve content of the collection.""" if isinstance(index, int): return self.__content[index] return WidgetGroup(self.__content[index]) def __len__(self) -> int: """Retrieve total number of items in the collection.""" return len(self.__content)