Fine-Tuning Settings for Widgets
Background
To bidirectionally sync a setting with a widget
, use the pattern:
self.settings.get_lq("my_setting").connect_to_widget(widget)
connect_to_widget
configures the widget’s behavior based on the attributes of my_setting
, as discussed here. This also affects the convenience methods New_UI
and new_default_widget
, see default widgets.
Compatibility matrix
Whether a setting can be connected to a widget depends on its dtype
. Compatibility includes:
float | int | str | bool | |
---|---|---|---|---|
QtWidgets.QDoubleSpinBox | ✅ default | ✅ default | ❌ | ? |
QtWidgets.QSlider | ✅ | ✅ | ❌ | ? |
pyqtgraph.widgets.SpinBox.SpinBox | ✅ default² | ✅ default² | ❌ | ? |
QtWidgets.QProgressBar | ✅ * | ? | ❌ | ? |
QtWidgets.QLCDNumber | ? | ? | ❌ | ? |
QtWidgets.QCheckBox | ❌ | ❌ | ❌ | ✅ default |
QtWidgets.QPlainTextEdit | ? | ? | ✅ default | ? |
QtWidgets.QLabel | ? | ? | ✅ | ? |
QtWidgets.QComboBox | ✅ default³ | ✅ default³ | ✅ default³ | ? |
QtWidgets.QPushButton | ❌ | ❌ | ❌ | ☑ see State-Buttons |
… list might be incomplete |
?: untested or discouraged.
*only tested for values between 0-100.
default² becomes the default widget for SI units.
default³ becomes the default widget if choices is defined.
Settings attributes
Display more decimal places
self.settings.New("precise_number", dtype=float, spinbox_decimals=6)
Restrict the values the widget can take
self.settings.New("constraint_number", vmin=-3, vmax=10)
Note: vmin
and vmax
only limit the widget’s range. The value itself may still be outside the range.
Add units
self.settings.New(..., unit="V")
Appends “V” after the number.
Add SI units
The value is displayed using prefixes like ’m’, ‘k’, ‘M’, ‘G’, etc.
self.settings.New(..., dtype=float, unit="s", si=True)
If the value is 0.001302 seconds, the widget will display 1.302 ms
.
Change the step size of spin boxes
This sets the increment when clicking the up/down arrows.
self.settings.New(..., dtype=float, spinbox_step=3.1415)
Arrays
N-dimensional arrays
are supported, but you need to set the is_array=True
flag:
self.settings.New("arr", dtype=int, is_array=True, initial=[[1, 2], [3, 4]])
File and folder paths
To specify a folder, we recommend:
self.settings.new_file("my_folder", is_dir=True)
To specify a file path with file filters, e.g.,
png
, use:self.settings.new_file("image", str, file_filters=("png files (*.png)",))
Dropdown menu and choices
If the setting takes a discrete set of values, it is often wise to specify choices. If choices are defined, QtWidgets.QComboBox
becomes the default widget. There are options to define choices.
Displayed and underlying values are different:
choices = (("one", 1), ("two", 2), ("three", 3)) self.settings("counting", int, choices=choices)
Note, that the value can only be updated with the underlying value.
self.settings["counting"] = 2
Displayed and underlying values are the same:
choices = ("red", "orange", "green") self.settings("traffic_light", str, choices=choices)
The list of choices can be altered dynamically:
lq.change_choice_list(("red", "yellow", "green")) # replaces existing choices
lq.add_choices(("violet",))
lq.remove_choices(("orange", "green"))
Read only
Make read-only (user cannot manipulate value through associated UI widgets):
self.settings.New(..., ro=True)
This property can be changed dynamically:
lq.change_readonly(ro=True)
New in ScopeFoundry 2.1: change_readonly_on
Let a setting decide to go in readonly mode when another setting updates. In the example,
other_lq = self.settings.New("crazy_values", float)
self.settings.New("anxious").change_readonly_on(other_lq, func=lambda x: x>100):
the “anxious” setting goes to readonly mode when the value of other_lq
exceeds 100.
State-Buttons
A bool-valued setting can produce a button that toggles and displays the state.
lq = self.settings.New("is_driving", bool, initial=False) ... btn = lq.new_pushButton(("halted - accelerate!", "driving - break!"))
To connect a bool
lq
to a QPushButtonbutton
, we recommend using connect_to_pushButton, as it allows to further specify the the displayed text and color.lq.connect_to_pushButton(button, ("halted - accelerate!", "driving - break!"))
Description
self.settings.New("pi", int, initial=3, description="the ratio of circumference to diameter is 3.0 <i>by law</i>.", ro=True)
The description is shown when hovering over the widget.
Command
Experimental, New in ScopeFoundry 2.0
self.settings.New("open png", str, is_cmd=True)
The default widget contains a button that, when clicked, runs the command in a detached process.
Copy to clipboard
New in ScopeFoundry 2.0
self.settings.New("passkey", str, is_clipboardable=True)
The default widget contains a button that, when clicked, copies the content to the clipboard.
This can be combined with is_cmd
.
Default widget
The connect_to_widget
function is also invoked through these patterns:
default_widget = self.settings.get_lq("my_setting").new_default_widget() # implicitly calls connect_to_widget
widget = self.settings.New_UI() # implicitly calls new_default_widget()
The default_widget
is determined by the dtype
of the setting. Refer to the compatibility matrix for the default widget associated with each dtype
.
New in ScopeFoundry 2.0
You can override the default widget at the time of definition using the default_widget_factory
argument. For example, the compatibility matrix tells us that int
is compatible with QtWidgets.QSlider
:
self.settings.New("b", dtype=int, vmin=0, vmax=255, default_widget_factory=QtWidgets.QSlider)