1
- ==============================
2
- Write a Custom Plugin (Expert )
3
- ==============================
1
+ =======================================
2
+ Write a Custom Device Plugin (Advanced )
3
+ =======================================
4
4
5
5
**navigate **'s :doc: `plugin system <plugin/plugin_home >` enables users to
6
- easily incorporate new devices and integrate new features and acquisition modes. In
7
- this guide, we will add a new device, titled ``CustomDevice ``, and a dedicated GUI
6
+ easily incorporate new devices and integrate new features and acquisition modes. In
7
+ this guide, we will add a new device type , titled ``CustomDevice ``, and a dedicated GUI
8
8
window to control it. This hypothetical ``CustomDevice `` is capable of moving a certain
9
- distance, rotating a specified number of degrees, and applying a force to halt its
9
+ distance, rotating a specified number of degrees, and applying a force to halt its
10
10
movement.
11
11
12
- **navigate ** plugins are implemented using a Model-View-Controller architecture. The
12
+ **navigate ** plugins are implemented using a Model-View-Controller architecture. The
13
13
model contains the device-specific code, the view contains the GUI code, and the
14
14
controller contains the code that communicates between the model and the view.
15
15
@@ -18,7 +18,7 @@ controller contains the code that communicates between the model and the view.
18
18
Initial Steps
19
19
-------------
20
20
21
- To ease the addition of a new plugin, we have created a template plugin that can be
21
+ To ease the addition of a new plugin, we have created a template plugin that can be
22
22
used as a starting point.
23
23
24
24
* Go to `navigate-plugin-template <https://github.com/TheDeanLab/navigate-plugin-template >`_.
@@ -89,9 +89,9 @@ Create a new custom device using the following code.
89
89
}
90
90
91
91
92
- All devices should be accompanied by synthetic versions, which enables the software
93
- to run without the hardware connected. Thus, in a manner that is similar to the
94
- ``CustomDevice `` class, we edit the code in ``synthetic_device.py ``, albeit without
92
+ All devices should be accompanied by synthetic versions, which enables the software
93
+ to run without the hardware connected. Thus, in a manner that is similar to the
94
+ ``CustomDevice `` class, we edit the code in ``synthetic_device.py ``, albeit without
95
95
any calls to the device itself.
96
96
97
97
.. code-block :: python
@@ -150,15 +150,15 @@ any calls to the device itself.
150
150
}
151
151
152
152
153
- Edit ``device_startup_functions.py `` to tell **navigate ** how to connect to and start
153
+ Edit ``device_startup_functions.py `` to tell **navigate ** how to connect to and start
154
154
the ``CustomDevice ``. This is the portion of the code that actually makes a connection
155
- to the hardware. ``load_device() `` should return an object that can control the
155
+ to the hardware. ``load_device() `` should return an object that can control the
156
156
hardware.
157
157
158
- **navigate ** establishes communication with each device independently, and passes the
159
- instance of that device to class that controls it (e.g., in this case, the
160
- `CustomDevice ` class). This allows **navigate ** to be initialized with multiple
161
- microscope :ref: `configurations <user_guide/software_configuration:configuration file >`,
158
+ **navigate ** establishes communication with each device independently, and passes the
159
+ instance of that device to class that controls it (e.g., in this case, the
160
+ `CustomDevice ` class). This allows **navigate ** to be initialized with multiple
161
+ microscope :ref: `configurations <user_guide/software_configuration:configuration file >`,
162
162
some of which may share devices.
163
163
164
164
.. code-block :: python
@@ -325,17 +325,17 @@ to ``custom_device_frame.py``, and edit the code as follows.
325
325
.. tip ::
326
326
327
327
**navigate ** comes equipped with a large number of validated widgets,
328
- which prevent users from entering invalid values that can crash the program or
329
- result in undesirable outcomes. It is highly recommended that you use these,
328
+ which prevent users from entering invalid values that can crash the program or
329
+ result in undesirable outcomes. It is highly recommended that you use these,
330
330
which include the following:
331
331
332
- * The ``LabelInput `` widget conveniently combines a label and an input widget
332
+ * The ``LabelInput `` widget conveniently combines a label and an input widget
333
333
into a single object. It is used to create the ``step_size `` and ``angle ``
334
334
widgets in the code above.
335
335
* The ``LabelInput `` widget can accept multiple types of ``input_class `` objects,
336
- which can include standard tkinter widgets (e.g., spinbox, entry, etc.) or
336
+ which can include standard tkinter widgets (e.g., spinbox, entry, etc.) or
337
337
custom widgets. In this example, we use the ``ttk.Entry `` widget.
338
- * Other examples of validated widgets include a ``ValidatedSpinbox ``,
338
+ * Other examples of validated widgets include a ``ValidatedSpinbox ``,
339
339
``ValidatedEntry ``, ``ValidatedCombobox ``, and ``ValidatedMixin ``.
340
340
* Please see the :any: `navigate.view.custom_widgets ` module for more details.
341
341
@@ -420,17 +420,17 @@ as follows.
420
420
self .parent_controller.execute(" stop_custom_device" )
421
421
422
422
423
- In each case above, the sub-controller for the ``custom-device `` establishes what
424
- actions should take place once a button in the view is clicked. In this case, the
425
- methods ``move_device ``, ``rotate_device ``, and ``stop_device ``. This triggers a sequence
423
+ In each case above, the sub-controller for the ``custom-device `` establishes what
424
+ actions should take place once a button in the view is clicked. In this case, the
425
+ methods ``move_device ``, ``rotate_device ``, and ``stop_device ``. This triggers a sequence
426
426
of events:
427
427
428
- * The sub-controller passes the command to the parent controller, which is the
428
+ * The sub-controller passes the command to the parent controller, which is the
429
429
main controller for the software.
430
- * The parent controller passes the command to the model, which is operating in
431
- its own sub-process, using an event queue. This eliminates the need for the
430
+ * The parent controller passes the command to the model, which is operating in
431
+ its own sub-process, using an event queue. This eliminates the need for the
432
432
controller to know anything about the model and prevents race conditions.
433
- * The model then executes command, and any updates to the controller from the
433
+ * The model then executes command, and any updates to the controller from the
434
434
model are relayed using another event queue.
435
435
436
436
-----------------
@@ -459,18 +459,18 @@ the file ``plugin_acquisition_mode.py``. The plugin folder structure is as follo
459
459
│ └── custom_device/
460
460
│ ├── device_startup_functions.py
461
461
│ ├── custom_device.py
462
- │ └── synthetic_device.py
462
+ │ └── synthetic_device.py
463
463
├── view/
464
464
| └── custom_device_frame.py
465
465
│
466
- └── plugin_config.yml
466
+ └── plugin_config.yml
467
467
468
468
469
469
Install the plugin using one of two methods:
470
- * Install a plugin by putting the whole plugin folder directly into
471
- ``navigate/plugins/ ``. In this example, put ``custom_device `` folder
470
+ * Install a plugin by putting the whole plugin folder directly into
471
+ ``navigate/plugins/ ``. In this example, put ``custom_device `` folder
472
472
and all its contents into ``navigate/plugins ``.
473
- * Alernatively, install this plugin through the menu
473
+ * Alernatively, install this plugin through the menu
474
474
:menuselection: `Plugins --> Install Plugin ` by selecting the plugin folder.
475
475
476
476
The plugin is ready to use. For this plugin, you can now specify a CustomDevice in the
@@ -489,7 +489,7 @@ The plugin is ready to use. For this plugin, you can now specify a CustomDevice
489
489
hardware :
490
490
type : CustomDevice
491
491
...
492
-
492
+
493
493
494
494
The ``custom_device `` will be loaded when **navigate ** is launched, and it can be
495
495
controlled through the GUI.
0 commit comments