Resolve "BEC Status Box for designer plugin"
Description
Takes !196 (merged) and fixes this issue.
BECDispatcher
is used in client and server, and name cannot be
hardcoded to "BECGuiClient" - BECDispatcher
is not a service, it is an utility class to have RedisConnector
working nicely with Qt.
Refactoring
The biggest change is commit 011103 , the comment in commit is copied below:
Inheriting from QTreeWidget causes havoc with display, also it is
important to parent items OR to give them a label otherwise it also
has display glitches.
Most of the time, composition has to be preferred over inheritance ;
inheritance is a question of behaviour - is the behaviour the same ?
Here, a widget is really not a BECConnector, but uses a BECConnector
(at least this is my understanding). Because a Widget and BECConnector
do not behave the same. It is easier, lighter to deal with single
inheritance.
The singleton usage is superfluous, since the underlying client is already
a singleton. Multiple BECConnector objects can be created, there won't
be more connections.
BECServiceStatusMixin has been removed in favor of the widget's own timer,
since it was causing "QObject::killTimer: Timers cannot be stopped from
another thread" errors (at least on my computer).
Also removes "redundant items check" ; where do those would come from?
Closes #245 (closed)
Merge request reports
Activity
changed milestone to %DT Milestone 2
added issuereproducible priorityneeded scopebackend stagepending typebug labels
assigned to @guijar_m
added 5 commits
- 5d435bd5 - refactor: simplify logic in bec_status_box
- 63a00563 - fix: add designer plugin classes
- f90bc00c - fix: make error StatusMessage in case service info msg is None
- 011103fd - refactor: put QTreeWidget in a container, rather than inheriting from it, and...
- e2f074b1 - fix: make main() function working, to be able to test out of Qt Designer
Toggle commit listmentioned in merge request !196 (merged)
22 23 # TODO : Put normal imports back when Pydantic gets faster 23 24 BECStatus = lazy_import_from("bec_lib.messages", ("BECStatus",)) 25 StatusMessage = lazy_import_from("bec_lib.messages", ("StatusMessage",)) 24 26 25 27 26 class BECStatusBoxConfig(ConnectionConfig): 27 pass 28 29 30 class BECServiceInfoContainer(BaseModel): 28 @dataclass 29 class BECServiceInfoContainer: 31 30 """Container to store information about the BEC services.""" 32 31 33 32 service_name: str 34 status: BECStatus | str = Field( 57 raise ValueError( 58 f"Status must be one of {BECStatus.__members__.values()} or 'NOTCONNECTED'. Input {v}" 59 ) 60 61 62 class BECServiceStatusMixin(QObject): 63 """A mixin class to update the service status, and metrics. 64 It emits a signal 'services_update' when the service status is updated. 65 66 Args: 67 client (BECClient): The client object to connect to the BEC server. 68 """ 69 36 70 services_update = Signal(dict, dict) 71 37 72 def __init__(self, client: BECClient): 21 22 22 23 # TODO : Put normal imports back when Pydantic gets faster 23 24 BECStatus = lazy_import_from("bec_lib.messages", ("BECStatus",)) 25 StatusMessage = lazy_import_from("bec_lib.messages", ("StatusMessage",)) 24 26 25 27 26 class BECStatusBoxConfig(ConnectionConfig): 114 if config is None: 115 config = BECStatusBoxConfig(widget_class=self.__class__.__name__) 116 else: 117 if isinstance(config, dict): 118 config = BECStatusBoxConfig(**config) 119 super().__init__(client=client, config=config, gui_id=gui_id) 120 QTreeWidget.__init__(self, parent=parent) 121 122 self.service_name = service_name 123 self.config = config 124 125 self.bec_service_info_container = {} 126 self.tree_items = {} 127 self.tree_top_item = None 61 QWidget.__init__(self, parent=parent) 62 self.setLayout(QVBoxLayout(self)) 333 243 """ 334 for _, (tree_item, status_widget) in self.tree_items.items(): 335 if tree_item == item: 336 status_widget.show_popup() 244 for _, objects in self.status_container.items(): 245 if objects["item"] == item: 246 objects["widget"].show_popup() 337 247 338 248 def closeEvent(self, event): 339 super().cleanup() 340 QTreeWidget().closeEvent(event) 249 self.connector.cleanup() 341 250 342 251 343 252 def main(): 344 253 """Main method to run the BECStatusBox widget.""" 55 self.config = config 33 def __init__(self, parent: QWidget = None, config=None): 56 34 QWidget.__init__(self, parent=parent) 35 if config is None: 36 # needed because we need parent to be the first argument for QT Designer 37 raise ValueError( 38 "Please initialize the StatusItem with a BECServiceInfoContainer for config, received None." 39 ) 40 self.config = config 57 41 self.parent = parent 58 42 self.layout = None 59 self.config = config 60 self._popup_label_ref = {} 61 43 self._label = None 62 44 self._icon = None 45 self.icon_size = (24, 24)