Releases: jdranczewski/puzzlepiece
v0.11.0
Added a tutorial! Check it out at https://puzzlepiece.readthedocs.io/en/stable/tutorial.html
New features:
- Puzzles can be indexed in additional ways as a shortcut - you can now directly say
puzzle["piece:param"]
to get a param. This also autocompletes in IPython. - Child params and actions - use
Popup.make_child_params
to easily create settings popups that modify hidden params. replace_piece
- an experimental method to update a Piece in place.done_signal
for the LiveWorker emitted when it finishes.- new extra module:
ipython_shims
adds two convenient magics:%%pzp_script
and%%safe_run
- Improvements to
DataGrid
s, including support for customRow
s inadd_row
andPopup
s for the Rows. - Ability to set a
Popup
's title.
Fixes:
call_stop
stops threads too.- reduced reliance on Qt spreadsheets - param changes should always indicate correctly with a red background now.
v0.10.0 - DataGrids, sliders, shortcuts, fixes
New shortcuts:
- The QApp and Puzzle name arguments are no longer required when creating a Puzzle. The QApp still needs to be created in non-IPython contexts, but it can now be inferred by the Piece.
- You can directly accesss a Piece's params by indexing it like a dictionary:
puzzle["piece"]["param_name"]
# is now equivalent to
puzzle["piece"].params["param_name"]
New features:
- A slider parameter type - displays a slider and a value label. Min and max values, as well as the step size, are defined on creation.
- First
extra
submodule -DataGrid
s allow for storing and interacting with data using theparam
abstractions in a table format. Can be added to a Piece'scustom_layout
to enable new data manipulation tasks.
Fixes and enhancements:
- add_piece now returns the Piece instance (useful if a class is being passed for instantiation)
v_step
argument when creating spinboxes changes the step of the box's buttons.- Popups now close when the Puzzle is closed.
- Default param values are cast to the right type on creation.
- IPython exception handler is now inserted correctly even if
puzzle.process_events()
is called in the cell that creates the Puzzle. - Pieces can now be instantiated without a parent Puzzle. This allows for using the Piece as a standalone Widget in an environment where only one Piece is needed, or a Puzzle cannot be set up, but is in general not advised.
- Option to hide the bottom buttons of a Puzzle (Tree, Export, STOP)
- All code has been re-formatted using ruff.
v0.9.0 - Popups, progress bars, IPython exceptions, fixes
Popups are now available as a convenient way to create a modal window attached to the main Puzzle. Can be used for calibration processes, further settings, or just in general GUI that you don't want cluttering a Piece. See https://puzzlepiece.readthedocs.io/en/latest/puzzlepiece.piece.html#puzzlepiece.piece.Popup for details.
Progress bar params give you a standard way to indicate progress, with tqdm-like iterable wrapping capability:
for i in piece.params['progress'].iter(range(10)):
print(i)
# this will automatically update the progress bar as the iteration goes on
puzzle.process_events() # you may need to refresh the Puzzle to display changes
Exceptions that arise when running in IPython and interacting with the GUI will now display an error dialog just like when running in non-interactive Python. Exceptions that arise during cell execution will still produce a traceback in the Notebook, as before.
Small fixes: all threads now stop when an exception is raised, and a getter result will be cast to the param's type if obtained during a set_value
call (that is if the setter doesn't return a value and a getter is present).
See pull request #2 for full changes
set_value and set_partial updates
set_value()
now returns the new value, as it may be different than the one being set if the setter returns a value or a getter is defined.
ParamArray
has a new property set_partial
which allows you to set values to slices of the stored numpy array. This calls the setter of the param.
puzzle['piece'].params['image'].set_partial[100:200, :] = 128
Convenient shortcuts
You can now access the QApplication class as puzzlepiece.QApp
, and pass Piece classes to add_piece
instead of instantiating them first - this will reduce the clutter when building applications, and bring the minimum viable app to this neater form:
import puzzlepiece as pzp
from puzzlepiece.pieces import random_number
app = pzp.QApp([])
puzzle = pzp.Puzzle(app, "Basic example")
puzzle.add_piece("random", random_number.Piece, 0, 0)
puzzle.show()
app.exec()
Ensurers - capture_exception
Small amendment to v0.6.0: ensurers can now capture the exception when called directly, so they can be used in if
statements easily.
# This will not raise an Exception is the check fails
if self._ensure_connected(capture_exception=True):
print("laser is connected!")
Original v0.6.0 changelog follows:
An ensurer is a decorator that can be placed on getters, setters, and actions, and it will run ahead of these functions. The intended behaviour is performing checks ahead of running the function - for example checking if a laser is connected ahead of trying to set its power. This way one ensurer can be written and used in multiple places easily.
See https://puzzlepiece.readthedocs.io/en/latest/puzzlepiece.piece.html#puzzlepiece.piece.ensurer for examples
Ensurers
An ensurer is a decorator that can be placed on getters, setters, and actions, and it will run ahead of these functions. The intended behaviour is performing checks ahead of running the function - for example checking if a laser is connected ahead of trying to set its power. This way one ensurer can be written and used in multiple places easily.
See https://puzzlepiece.readthedocs.io/en/latest/puzzlepiece.piece.html#puzzlepiece.piece.ensurer for examples
Globals - variable management
It's now easier for multiple Pieces to share a device SDK with each other - they can put a hold on it in puzzle.globals
and release it when done, only setting up and closing the SDK once for all Pieces.
See https://puzzlepiece.readthedocs.io/en/latest/puzzlepiece.puzzle.html#puzzlepiece.puzzle.Globals for examples
Array and Dropdown params
Array params let you properly communicate more complex data, like images or spectra, through the unified puzzlepiece API. They use numpy arrays as the data format.
Dropdown params can be populated with default values at startup and make it much easier to select device serial numbers.
The setup method of a Piece is now called ahead of param definition, so that dropdown params can use a device SDK to search for available devices.
Revamp params
The previous design of how params handled being set programmatically and from input fields mostly worked, but was rather convoluted, and limited the precision of the stored value to the display precision, which is very silly.
The back-end way params work and the associated signalling has thus been reworked, and new tests were introduced to test for correctness of the new behaviour.
See af35244 for the exact changes, but most of the behaviour should be unchanged. Most notably:
- params no longer have limited precision, should go as precise as float allows
- the
changed
Signal is now emitted every timeset_value
is called, even if the value didn't necessarily change - if implementing custom params,
_input_set_value
should block any Signals emitted by changing the input using this method. This can be achieved usingself.input.blockSignals(True)
andself.input.blockSignals(False)