spacr.qt.widgets.measure_input_table¶
The FEATURES table: rows are fields, columns are channels and mask types.
The one control the Measure module has no equivalent of. Measure reads a
merged/ folder a pipeline already built, and everything about which file
is which channel was decided by the plate’s naming convention long before
Measure saw it. A user who drew masks with a mouse has no naming convention
and no pipeline, so the question has to be asked, and this is where it is
asked: one row per field, one column per channel and per mask type, and three
ways to fill a cell – drop files on it, click it and browse, or write one
regex that fills the whole table at once.
The model behind it is spacr.measure.FieldTable, which is Qt-free
and is what spacr.measure.measure_from_field_table() consumes. This
module holds no measurement knowledge of its own: it edits that table and
shows what it says.
Classes¶
Edit a |
Functions¶
|
Every file among |
|
What a mask column is called on screen. |
Module Contents¶
- class spacr.qt.widgets.measure_input_table.MeasureInputTable(parent: PySide6.QtWidgets.QWidget | None = None, *, threaded: bool = True)[source]¶
Bases:
PySide6.QtWidgets.QWidgetEdit a
spacr.measure.FieldTableby dropping, browsing or regex.- Parameters:
parent – parent widget, or
None.- Variables:
table_changed – emitted whenever the table or its problems change, so the window around it can refresh the derived settings and the Run button together.
Build the table, its column controls and its regex box.
- Parameters:
parent – parent widget, or
None.threaded – run the walk over dropped folders on a worker.
Falseruns it inline, so a test can drop a folder and read the table on the next line.
- add_dropped(paths: Sequence[Any]) None[source]¶
Add every file under
paths, once a worker has expanded them.SPLIT FROM
add_paths(), and the split is the fix for a frozen application. Everything here is a list of strings; theisdirandlistdirthat turn a dropped folder into files run on this widget’s own worker (files_under()), because a drop is a path the user chose and on a microscope rig that is the share the images live on – one stat under a sleepingautofsmount was measured at over twenty seconds, on the thread that paints.NOTHING IS ADDED BY THE TIME THIS RETURNS, which is the point. Read the table from
table_changed, not from the line after this.- Parameters:
paths – files and folders from a drop or a file dialog.
- Returns:
None. The count does not exist yet.
- add_paths(paths: Sequence[Any]) int[source]¶
Sort
pathsinto the table with the current regex.Synchronous, and safe to be: the regex is matched against each path’s BASENAME, so sorting files into cells is string work that touches no filesystem. Anything that might be a FOLDER must come through
add_dropped()instead, which expands it on a worker first.- Parameters:
paths – file paths, as strings or anything
straccepts.- Returns:
how many of them landed in a cell.
- assign_file(row: int, column: str, path: str) bool[source]¶
Put one file in one cell, as double-clicking and browsing does.
- Parameters:
row – the row’s position in the table.
column –
'channel:<index>'counting from zero, or a mask role name.path – the file to put there.
- Returns:
whether the cell existed and took it.
- clear() None[source]¶
Forget every row and every file that was ever dropped.
The channel-token memory goes with them: an empty table’s columns mean nothing yet, and keeping the old ranking would let a token the user has cleared decide where the next drop’s files land.
- dragEnterEvent(event)[source]¶
Accept a drag that carries local files.
Decided from the mime data alone. Asking the filesystem whether the drag is worth accepting would run a stat on the GUI thread for every drag-move event the pointer produces.
- Parameters:
event – the Qt drag event.
- dragMoveEvent(event)[source]¶
Keep accepting while local files stay over the table.
- Parameters:
event – the Qt drag event.
- dropEvent(event)[source]¶
Sort the dropped files into rows and columns.
Returns before anything is assigned when a folder was dropped: the folder is expanded on a worker. Read the table from
table_changed, not from the line after this one.- Parameters:
event – the Qt drop event.
- is_scanning() bool[source]¶
True while a walk started by
add_dropped()is still running.
- reapply_regex() int[source]¶
Sort every file this table has ever been given, again.
The cells are emptied first, so a corrected regex REPLACES the previous assignment instead of adding a second one beside it.
- Returns:
how many files landed in a cell.
- set_file_picker(picker) None[source]¶
Replace the modal file chooser with
picker(caption) -> path.Headless Qt refuses a static modal – it runs its event loop in C++ and hangs the run – so a test drives the browse path through this rather than through
QFileDialog.- Parameters:
picker – callable given the dialog caption and returning the chosen path, or an empty value for no choice;
Nonerestores the file dialog.
- set_regex(pattern: str) None[source]¶
Put
patternin the regex box and sort the known files again.- Parameters:
pattern – regular expression matched against each file’s basename; its named groups (such as
field,channelandmask) decide the cell a file lands in. The cells are emptied and every known file re-sorted.
- spacr.qt.widgets.measure_input_table.files_under(paths: Sequence[str]) List[str][source]¶
Every file among
paths, with any folder expanded one level.A user who drew masks for six fields drops the folder, not the files, so a drop that refused a directory would refuse the ordinary case.
NOT FOR THE GUI THREAD. Every path here is one the user chose, which on a microscope rig means a network share, and the
isdiris what wakes the automount.MeasureInputTable.add_dropped()is the only caller and it runs this on a worker. Looked up through the module global so a test can replace it and see which thread it ran on.- Parameters:
paths – what was dropped or chosen.
- Returns:
the files, folders expanded, in a stable order.
- spacr.qt.widgets.measure_input_table.role_caption(role: str) str[source]¶
What a mask column is called on screen.
An organelle slot reads as a number –
Organelle 2– never as the lettered role it is stored under, the same caption the settings forms and the Import Project screen give it.- Parameters:
role – a role from
spacr.crops.MASK_PLANE_ORDER.- Returns:
the column heading.