spacr.qt.widgets.import_workbench¶
Preview how imported image names map to a spaCR folder structure.
Drop images into the table, review or edit the inferred filename pattern,
and assign a role to each captured group. The preview updates after every
edit and does not write or move files. Pattern inference is provided by
spacr.regex_infer; the displayed plan comes from
spacr.import_plan.
Classes¶
The table, the regex, the roles and the preview, in one panel. |
|
The workbench in a window, returning the accepted regex. |
Functions¶
|
Every image among |
Module Contents¶
- class spacr.qt.widgets.import_workbench.ImportWorkbench(filenames: Sequence[str] = (), regex: str = '', parent: PySide6.QtWidgets.QWidget | None = None)[source]¶
Bases:
PySide6.QtWidgets.QWidgetThe table, the regex, the roles and the preview, in one panel.
- Parameters:
filenames – the names to work the pattern out from. Copied to a list of strings, so a generator or a set of paths is accepted and the caller’s sequence is not consumed.
regex – the pattern to start from. Empty starts with none, which is the ordinary case – working the pattern out is what this is for.
parent – parent widget.
Build the workbench: the files, the pattern, and what it would produce.
The walk over dropped paths runs on its own worker. A drop is a path the user chose, and a plate lives on the microscope’s share: one
os.path.existsunder a sleeping autofs mount had not returned after twenty seconds, and a walk is thousands of those. Inline, the drop froze the application with no traceback – a stalled event loop is not a crash, and it was reported as hover flicker and glimpses of other screens. The runner is marked not user-visible because dropping a folder is not starting a run, and it is safe to do so because that runner carries nothing but the walk.- Parameters:
filenames – files to start with.
regex – pattern to start with; empty waits for Propose.
parent – parent widget, or
None.
- add_files(paths: Sequence[str]) None[source]¶
Add every image under
paths, once a worker has found them.SPLIT IN TWO, and the split is the fix for a frozen application. Everything here is a list of strings and a caption; the walk runs on this panel’s own worker (
_walk(), wrappingimages_under()) because it is anisdirand a recursiveos.walkover a path the user chose, which on one such workstation is anautofsshare that took twenty seconds to answer a single stat._files_found()takes the answer back on the GUI thread.Nothing is added by the time this returns, which is the point. Read
files()from a redraw, not from the line after this one.Two drops in a row start two walks rather than one: unlike a refresh, they ask DIFFERENT questions, and coalescing them would lose a plate. Nothing here is shared mutable state – both answers arrive on the GUI thread and both are kept.
- ask_for_files() None[source]¶
Ask for images through a file dialog.
RETURNS NOTHING, AND THAT IS THE CHANGE. It used to answer with how many files were taken, which it could only do by walking every dropped folder before returning – on the GUI thread, which is the freeze this module was rewritten to remove.
add_files()hands the walk to a worker now, so the count does not exist yet when this returns; it arrives at_files_found().A caller that wants the number should watch the table, not this.
- closeEvent(event)[source]¶
Stop background work and unlink before going away.
- Parameters:
event – the Qt close event.
- dragEnterEvent(event)[source]¶
Accept a drag carrying images.
- Parameters:
event – the Qt drag event.
- dragMoveEvent(event)[source]¶
Keep accepting while images stay over the workbench.
- Parameters:
event – the Qt drag event.
- dropEvent(event)[source]¶
Take the dropped images and work out their naming pattern.
- Parameters:
event – the Qt drop event.
- is_scanning() bool[source]¶
True while a walk started by
add_files()is still running.
- set_files(paths: Sequence[str]) None[source]¶
Replace the file set and re-propose a pattern for it.
A REGEX PROPOSED FOR THE OLD SET IS NOT PROPOSED FOR THIS ONE. The pattern is inferred from what varies across the names, so carrying it over would describe a set the user has replaced.
ANY WALK STILL RUNNING IS ABANDONED.
The Clear button lands here, and a walk of a share that is not answering is precisely the one the user gives up on. Without the cancel its result arrives half a minute later and quietly refills the table that was just emptied.
JobRunner.cancelbumps a generation, so the result is dropped on arrival rather than handed to_files_found(); the thread is left to retire itself, because joining it here would be the freeze this all exists to remove.- Parameters:
paths – the image paths.
- class spacr.qt.widgets.import_workbench.ImportWorkbenchDialog(filenames: Sequence[str] = (), regex: str = '', parent: PySide6.QtWidgets.QWidget | None = None)[source]¶
Bases:
PySide6.QtWidgets.QDialogThe workbench in a window, returning the accepted regex.
- Parameters:
filenames – the names to work the pattern out from.
regex – the pattern to start from.
parent – parent widget.
Both are handed to the
ImportWorkbenchthis wraps, which documents what they mean.Wrap the workbench in a window with OK and Cancel.
- Parameters:
filenames – files to start with.
regex – pattern to start with.
parent – parent widget, or
None.
- chosen_regex() str[source]¶
Return the accepted pattern for
_get_regexcustom mode.The workbench previews patterns against complete filenames, while
_get_regexappends the selected image extension. This method removes that trailing extension withfor_get_regex()to avoid duplicating it in the import pattern.
- done(result: int) None[source]¶
Close, and let no walk outlive the dialog.
donerather thancloseEventbecause it is the one funnel: Ok, Cancel and the window’s close button all arrive here, and a dialog dismissed while the share is still being walked is the ordinary case – it is why the user gave up on it.
- spacr.qt.widgets.import_workbench.images_under(paths: Sequence[str], *, limit: int = 5000) List[str][source]¶
Every image among
paths, walking any folder given.- Parameters:
paths – files and directories from the drop or file picker. Supported files are kept directly and directories are walked recursively.
limit – stop after this many. A plate is tens of thousands of files and the table is a PREVIEW – the regex is inferred from an aligned set, and the set does not have to be all of it.
NOT FOR THE GUI THREAD. Every path here is one the user chose, which on a microscope rig means the share the images live on: the
isdiris what wakes anautofsmount, and the walk is thousands more stats behind it. Call it from_walk()on a worker –ImportWorkbench.add_files()is the only caller in this module and that is what it does.