Dynamical Widgets
New in ScopeFoundry 2.0
You can add and remove settings anywhere in the code using:
self.settings.New("q_position")
and
self.settings.remove("q_position")
The same applies to operations:
self.operations.new("praise", self.praise)
where self.praise
is a callable without parameters.
self.operations.remove("praise")
If a setting is added or removed dynamically (i.e., not at startup), the settings tree in the sidebar updates automatically by adding or removing a default widget. You can add this behavior to your custom view of a Measurement
or DataBrowserView
.
The following examples show how to create dynamic widgets from a settings container. The dynamic widget will include the “connected” setting and will dynamically add widgets for any setting matching the pattern *_position
.
Finally, learn how to create sidebar trees yourself.
Create a new widget that listens for the addition and removal of settings
Given self.settings
:
dyn_widget = self.settings.New_UI(include=("connected", "*_position"))
which is equivalent to:
from ScopeFoundry import new_widget
...
dyn_widget = new_widget(self.settings, include=("connected", "*_position"))
The new_widget
function accepts other arguments like title
, exclude
, and style
(“form”, “hbox”, “scroll_form”).
Add to an existing layout
from ScopeFoundry import add_to_layout
...
# layout = your_widget.layout()
add_to_layout(self.settings, layout, include=("connected", "*_position"))
Supported layouts
QtWidgets.QFormLayout
QtWidgets.QHBoxLayout
QtWidgets.QVBoxLayout
QtWidgets.QGridLayout
Generalizations
The same functions can be used on operations:
add_to_layout(self.operations, layout, include=("praise",))
dyn_widget = new_widget(self.operations, include=("praise",))
You can even use them on whole measurements, hardware, and apps—adding their operations and settings:
add_to_layout(my_measure, layout, include=("praise",))
More generally, anything that follows the Widgetable
protocol can be used with add_to_layout
and new_widget
:
class Widgetable(Protocol):
name: str
settings: LQCollection
operations: Operations
_widgets_managers_: List
You can import LQCollection
and Operations
from ScopeFoundry
. List
here simply refers to a standard Python list, []
.
Trees
Somewhat related, you can generate dynamic trees:
from ScopeFoundry.dynamical_widgets import new_tree_widget, new_widget
tree = new_tree_widget(my_widgetable_list)
The elements in the list need to follow the protocol:
class SubtreeAbleObj(Protocol):
name: str
settings: LQCollection
operations: Operations
_subtree_managers_: List
def on_new_subtree(self, subtree): ... # optional
def on_right_click(self): ... # optional
An example of such a Tree is the left panel in the default app.