mirror of
https://github.com/bec-project/bec_widgets.git
synced 2025-07-13 11:11:49 +02:00
docs(developer): tutorial for BECWidget base class
This commit is contained in:
@ -1,4 +1,4 @@
|
||||
(developer.bec_dispatcher)=
|
||||
(developer.widget_development.bec_dispatcher)=
|
||||
|
||||
# BECDispatcher
|
||||
|
||||
|
171
docs/developer/widget_development/widget_base_class.md
Normal file
171
docs/developer/widget_development/widget_base_class.md
Normal file
@ -0,0 +1,171 @@
|
||||
(developer.widget_development.widget_base_class)=
|
||||
|
||||
# BECWidget Base Class
|
||||
|
||||
When developing new widgets, it is crucial to ensure seamless integration with the BEC system. This is achieved by using
|
||||
the [`BECWidget`](https://bec.readthedocs.io/projects/bec-widgets/en/latest/api_reference/_autosummary/bec_widgets.utils.bec_widget.BECWidget.html#bec_widgets.utils.bec_widget.BECWidget)
|
||||
base class, which provides essential functionalities and shortcuts to interact with various BEC services. In this
|
||||
tutorial, we will explore the importance of this base class, the role of
|
||||
the [`BECConnector`](https://bec.readthedocs.io/projects/bec-widgets/en/latest/api_reference/_autosummary/bec_widgets.utils.bec_connector.BECConnector.html#bec_widgets.utils.bec_connector.BECConnector)
|
||||
mixin, and how these components work together to facilitate the development of powerful and responsive widgets.
|
||||
|
||||
## Understanding the `BECWidget` Base Class
|
||||
|
||||
The [`BECWidget`](https://bec.readthedocs.io/projects/bec-widgets/en/latest/api_reference/_autosummary/bec_widgets.utils.bec_widget.BECWidget.html#bec_widgets.utils.bec_widget.BECWidget)
|
||||
base class is designed to serve as the foundation for all BEC-connected widgets. It ensures that your widget is properly
|
||||
integrated with the BEC system by providing:
|
||||
|
||||
1. **Connection to BEC Services
|
||||
**: [`BECWidget`](https://bec.readthedocs.io/projects/bec-widgets/en/latest/api_reference/_autosummary/bec_widgets.utils.bec_widget.BECWidget.html#bec_widgets.utils.bec_widget.BECWidget)
|
||||
includes
|
||||
the [`BECConnector`](https://bec.readthedocs.io/projects/bec-widgets/en/latest/api_reference/_autosummary/bec_widgets.utils.bec_connector.BECConnector.html#bec_widgets.utils.bec_connector.BECConnector)
|
||||
mixin, which handles all the necessary connections to BEC services such as the BEC server, device manager, scan
|
||||
control, and more.
|
||||
|
||||
2. **Qt Integration**:
|
||||
The [`BECWidget`](https://bec.readthedocs.io/projects/bec-widgets/en/latest/api_reference/_autosummary/bec_widgets.utils.bec_widget.BECWidget.html#bec_widgets.utils.bec_widget.BECWidget)
|
||||
base class also ensures that your widget is correctly integrated with Qt by requiring that it inherits from
|
||||
both [`BECWidget`](https://bec.readthedocs.io/projects/bec-widgets/en/latest/api_reference/_autosummary/bec_widgets.utils.bec_widget.BECWidget.html#bec_widgets.utils.bec_widget.BECWidget)
|
||||
and [`QWidget`](https://doc.qt.io/qtforpython-6/PySide6/QtWidgets/QWidget.html). This combination allows your widget
|
||||
to leverage the full power of Qt for creating rich user interfaces while staying connected to the BEC ecosystem.
|
||||
|
||||
3. **Configuration Management**: The base class provides a `ConnectionConfig` model (based on Pydantic) that helps
|
||||
manage and validate the configuration of your widget. This configuration can be easily serialized to and from Python
|
||||
dictionaries, JSON, or YAML formats, allowing for persistent storage and retrieval of widget states.
|
||||
|
||||
4. **RPC Registration**: Widgets derived
|
||||
from [`BECWidget`](https://bec.readthedocs.io/projects/bec-widgets/en/latest/api_reference/_autosummary/bec_widgets.utils.bec_widget.BECWidget.html#bec_widgets.utils.bec_widget.BECWidget)
|
||||
are automatically registered with
|
||||
the [`RPCRegister`](https://bec.readthedocs.io/projects/bec-widgets/en/latest/api_reference/_autosummary/bec_widgets.cli.rpc_register.RPCRegister.html#bec_widgets.cli.rpc_register.RPCRegister),
|
||||
enabling them to handle remote procedure calls (RPCs) efficiently. This allows the widget to be controlled remotely
|
||||
from the `BECIPythonClient` via CLI, providing powerful control and automation capabilities. For example, you can
|
||||
remotely adjust widget settings, start/stop operations, or query the widget’s status directly from the command line.
|
||||
|
||||
Here’s a basic example of a widget inheriting
|
||||
from [`BECWidget`](https://bec.readthedocs.io/projects/bec-widgets/en/latest/api_reference/_autosummary/bec_widgets.utils.bec_widget.BECWidget.html#bec_widgets.utils.bec_widget.BECWidget):
|
||||
|
||||
```python
|
||||
from bec_widgets.utils.bec_widget import BECWidget
|
||||
from qtpy.QtWidgets import QWidget, QVBoxLayout
|
||||
|
||||
|
||||
class MyWidget(BECWidget, QWidget):
|
||||
def __init__(self, parent=None, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
QWidget.__init__(self, parent=parent)
|
||||
self.get_bec_shortcuts() # Initialize BEC shortcuts
|
||||
self.init_ui()
|
||||
|
||||
def init_ui(self):
|
||||
layout = QVBoxLayout(self)
|
||||
# Add more UI components here
|
||||
self.setLayout(layout)
|
||||
```
|
||||
|
||||
### The Role of `BECConnector`
|
||||
|
||||
At the heart
|
||||
of [`BECWidget`](https://bec.readthedocs.io/projects/bec-widgets/en/latest/api_reference/_autosummary/bec_widgets.utils.bec_widget.BECWidget.html#bec_widgets.utils.bec_widget.BECWidget)
|
||||
is
|
||||
the [`BECConnector`](https://bec.readthedocs.io/projects/bec-widgets/en/latest/api_reference/_autosummary/bec_widgets.utils.bec_connector.BECConnector.html#bec_widgets.utils.bec_connector.BECConnector)
|
||||
mixin, which plays a crucial role in managing the connection between your widget and the BEC system.
|
||||
The [`BECConnector`](https://bec.readthedocs.io/projects/bec-widgets/en/latest/api_reference/_autosummary/bec_widgets.utils.bec_connector.BECConnector.html#bec_widgets.utils.bec_connector.BECConnector)
|
||||
provides several key functionalities:
|
||||
|
||||
1. **Client Initialization**: It initializes a `BECClient` instance if one isn't provided, ensuring your widget is
|
||||
connected to the BEC server. This client is central to all interactions with the BEC system.
|
||||
|
||||
2. **Task Management**:
|
||||
The [`submit_task`](https://bec.readthedocs.io/projects/bec-widgets/en/latest/api_reference/_autosummary/bec_widgets.utils.bec_connector.BECConnector.html#bec_widgets.utils.bec_connector.BECConnector.submit_task)
|
||||
method allows for running tasks in separate threads, preventing long-running operations from blocking the main UI
|
||||
thread.
|
||||
|
||||
3. **Configuration Handling
|
||||
**: [`BECConnector`](https://bec.readthedocs.io/projects/bec-widgets/en/latest/api_reference/_autosummary/bec_widgets.utils.bec_connector.BECConnector.html#bec_widgets.utils.bec_connector.BECConnector)
|
||||
uses the `ConnectionConfig` model to manage the widget’s configuration, ensuring all parameters are validated and
|
||||
properly set up.
|
||||
|
||||
4. **RPC Registration**: Widgets are registered with
|
||||
the [`RPCRegister`](https://bec.readthedocs.io/projects/bec-widgets/en/latest/api_reference/_autosummary/bec_widgets.cli.rpc_register.RPCRegister.html#bec-widgets-cli-rpc-register-rpcregister),
|
||||
allowing them to handle remote procedure calls effectively.
|
||||
|
||||
5. **Error Handling**: It includes utilities for handling errors gracefully within the Qt environment, ensuring that
|
||||
issues are reported to the user without crashing the application.
|
||||
|
||||
### Utilizing `get_bec_shortcuts`
|
||||
|
||||
One of the most powerful features of
|
||||
the [`BECConnector`](https://bec.readthedocs.io/projects/bec-widgets/en/latest/api_reference/_autosummary/bec_widgets.utils.bec_connector.BECConnector.html#bec_widgets.utils.bec_connector.BECConnector)
|
||||
is the `get_bec_shortcuts` method. This method provides your widget with direct access to essential components of the
|
||||
BEC system through convenient shortcuts:
|
||||
|
||||
1. **Device Manager (`self.dev`)**:
|
||||
- Access all devices registered with the BEC system. You can interact with devices, retrieve their status, and send
|
||||
commands directly through this shortcut.
|
||||
```python
|
||||
# Moves 'motor1' to position 10
|
||||
self.dev["motor1"].move(10)
|
||||
```
|
||||
|
||||
2. **Scan Control (`self.scans`)**:
|
||||
- Control scans, initiate new ones, monitor progress, and manage their execution.
|
||||
```python
|
||||
# Starts Line Scan from -10 to 10 in samx and -5 to 5 in samy
|
||||
self.scans.line_scan(self.dev.samx,-10,10,self.dev.samy,-5,5, steps=100, exp_time=0.001,relative=False)
|
||||
```
|
||||
|
||||
3. **Queue Management (`self.queue`)**:
|
||||
- Manage the BEC scan queue, such as adding scans, checking status, or removing scans.
|
||||
```python
|
||||
# Request abortion of the current scan queue
|
||||
self.queue.request_scan_abortion()
|
||||
```
|
||||
|
||||
4. **Scan Storage (`self.scan_storage`)**:
|
||||
- Access stored scan data for retrieval and analysis.
|
||||
```python
|
||||
# Retrieve scan item for a specific scan ID
|
||||
self.scan_item = self.queue.scan_storage.find_scan_by_ID(self.scan_id)
|
||||
```
|
||||
|
||||
5. **Full BECClient Access (`self.client`)**:
|
||||
- Direct access to the BECClient instance, allowing for additional functionalities not covered by the shortcuts.
|
||||
```python
|
||||
# Shutdown the BECClient
|
||||
self.client.shutdown()
|
||||
```
|
||||
|
||||
### Example: `PositionerBox` Widget
|
||||
|
||||
Let’s look at an example of a widget that leverages
|
||||
the [`BECWidget`](https://bec.readthedocs.io/projects/bec-widgets/en/latest/api_reference/_autosummary/bec_widgets.utils.bec_widget.BECWidget.html#bec_widgets.utils.bec_widget.BECWidget)
|
||||
base class and `get_bec_shortcuts`:
|
||||
|
||||
````{dropdown} View code: PositionerBox Widget
|
||||
:icon: code-square
|
||||
:animate: fade-in-slide-down
|
||||
```{literalinclude} ../../../bec_widgets/widgets/positioner_box/positioner_box.py
|
||||
:language: python
|
||||
:pyobject: PositionerBox
|
||||
```
|
||||
````
|
||||
|
||||
In this widget:
|
||||
|
||||
- **Device Interaction**: The widget uses `self.dev` to interact with a positioner device, reading its state and
|
||||
updating the UI accordingly.
|
||||
|
||||
- **Scan and Queue Control**: Although not shown in this example, the widget could easily use `self.scans`
|
||||
and `self.queue` to manage scans related to the positioner or queue up new operations.
|
||||
|
||||
### Conclusion
|
||||
|
||||
The `BECWidget` base class and the `BECConnector` mixin are foundational components for creating widgets that seamlessly
|
||||
integrate with the BEC system. By inheriting from `BECWidget`, you gain access to powerful connection management, task
|
||||
handling, and configuration capabilities, as well as shortcuts that make interacting with BEC services straightforward
|
||||
and efficient.
|
||||
|
||||
By leveraging these tools, you can focus on building the core functionality of your widget, confident that the
|
||||
complexities of BEC integration are handled robustly and efficiently. In the next tutorial we will demonstrate
|
||||
step-by-step how to create a custom widget using the `BECWidget` base class and explore advanced features for creating
|
||||
responsive and interactive user interfaces.
|
@ -1,5 +1,6 @@
|
||||
(developer.widget_development)=
|
||||
# Widget development
|
||||
|
||||
# Widget Development
|
||||
This section provides an introduction to the building blocks of BEC Widgets: widgets. Widgets are the basic components of the graphical user interface (GUI) and are used to create larger applications. We will cover key topics such as how to develop new widgets or how to customise existing widgets. For details on the already available widgets and their usage, please refer to user section about [widgets](#user.widgets)
|
||||
|
||||
```{toctree}
|
||||
@ -9,5 +10,5 @@ hidden: false
|
||||
---
|
||||
|
||||
bec_dispatcher
|
||||
|
||||
widget_base_class
|
||||
```
|
Reference in New Issue
Block a user