spacr.qt.dnd_handlers

Per-module drop handlers.

Each pipeline app has different expectations for what a “source” means. This module encodes those policies as DropHandler subclasses that the AppScreen wires up at construction time.

Handler map (also read by get_handler):

App

Accepts

mask measure external_masks annotate classify make_masks map_barcodes umap ml_analyze regression recruitment activation analyze_plaques train_cellpose cellpose_masks cellpose_all other modules

folder w/ images (auto-parses regex + preview) folder named merged OR one containing merged/ mixed image/label files or folders; assignment table folder with measurements/measurements.db folder with data/ or measurements/ folder with images + optional masks/ folder with FASTQ; also a raw .fastq.gz drop folder with measurements/measurements.db ditto ditto + scores.csv folder with per-well recruitment CSVs folder with saved activation maps or the CV model dir folder with plaque images folder with image+mask pairs folder with images ditto an existing source folder or supported data file

Every handler falls back to CSV settings-import via spacr.qt.dnd so users can also drop a settings CSV on any screen to load it.

Attributes

Classes

AlignDropHandler

Use a dropped image folder (or one tile) as Align & Stitch input.

AnnotateDropHandler

Accept a plate folder with measurements/measurements.db or

BatchDropHandler

Load queue files or add dropped settings snapshots as jobs.

ClassifyDropHandler

Accept a plate folder with measurements/measurements.db or

CoefficientsDropHandler

Prediction Profiler: the regression coefficients under results/.

ConvertDropHandler

Use a dropped microscopy container or folder as converter input.

DataManagerDropHandler

Data Manager: set the project, then measure it.

DatabaseDropHandler

Open a dropped measurements database in the Database Browser.

EvaluationBundleDropHandler

Classifier Evaluation: the run folder holding the evaluation bundle.

ExternalMasksDropHandler

Append mixed intensity images and external label masks to the mapper.

ForeignProjectDropHandler

Populate Import Project from image folders, tables and mapping files.

ImageFieldsDropHandler

Image-folder input shared by Model Compare.

LabelMaskDropHandler

Curate and Napari Bridge: one label mask, from wherever you drop.

LayerStackDropHandler

Layer Viewer: the dropped array, added as an image or as labels.

LayoutDropHandler

Drop policy for a screen that names what it wants, not where it is.

LineageDropHandler

Lineage: a database path field and one load.

MakeMasksDropHandler

Accept a folder with images (or image+mask pairs).

MapBarcodesDropHandler

Accept a FASTQ file (.fastq/.fastq.gz) or a folder

MaskDropHandler

Accept a folder of raw microscopy images and preview its filename

MeasureDropHandler

Accept the merged folder produced by the mask module, or a

MeasurementsDropHandler

Accept a database, its measurements folder, or its plate folder.

MethodsSourcesDropHandler

Methods & Results: fill whichever of its four source fields fits.

ModelZooDropHandler

Scan checkpoints, or use image-only folders as benchmark fields.

PlateQueueDropHandler

Queue plate folders that carry spaCR settings snapshots.

ProjectFolderDropHandler

A screen that takes a whole project, wherever inside it you drop.

ProjectRootsDropHandler

Project Browser: several folders at once, each becoming a root.

ReportDropHandler

Accept a completed spaCR run folder and scan its report inputs.

ResultsDatabaseDropHandler

Database input for Plate Viewer and Annotator Agreement.

ResultsFolderDropHandler

Hit List: the results/ folder a regression wrote.

RunHistoryDropHandler

Run History: select the run a dropped run folder belongs to.

ScatterTableDropHandler

Image Scatter: a path field, a table picker, then the read.

SourceDropHandler

General source-path policy for modules without a narrower contract.

SubmissionSettingsDropHandler

Distributed Jobs: a settings snapshot to submit, or the plate with one.

TableDropHandler

A screen that reads one table: the explorers, the plotters, the gates.

TrainingRunsDropHandler

Accept a directory and asynchronously scan it for training runs.

Functions

active_scan_jobs(→ int)

How many folder-scan threads screen still owns.

get_handler(→ spacr.qt.dnd.DropHandler)

Return a fresh DropHandler for app_key.

scan_folder_structure(→ Dict[str, Any])

Walk a dropped folder ONCE and return the folder-metadata report.

scan_is_busy(→ bool)

True while a dropped folder is still being walked for screen.

scan_mask_folder(→ Dict[str, Any])

List the top level of a dropped folder once. Worker-safe.

table_names(→ List[str])

Return the tables in a SQLite file, or [] for anything else.

Module Contents

class spacr.qt.dnd_handlers.AlignDropHandler[source]

Bases: spacr.qt.dnd.DropHandler

Use a dropped image folder (or one tile) as Align & Stitch input.

apply(path: pathlib.Path, screen) None[source]

Wire path into screen (set src, populate settings, etc.).

can_accept(path: pathlib.Path) bool[source]

Return True if path (folder OR file) is usable as-is.

error_message(path: pathlib.Path) str[source]

Human-friendly explanation for why path can’t be used.

class spacr.qt.dnd_handlers.AnnotateDropHandler[source]

Bases: spacr.qt.dnd.DropHandler

Accept a plate folder with measurements/measurements.db or the .db file itself.

apply(path: pathlib.Path, screen) None[source]

Wire path into screen (set src, populate settings, etc.).

can_accept(path: pathlib.Path) bool[source]

Return True if path (folder OR file) is usable as-is.

error_message(path: pathlib.Path) str[source]

Human-friendly explanation for why path can’t be used.

class spacr.qt.dnd_handlers.BatchDropHandler[source]

Bases: spacr.qt.dnd.DropHandler

Load queue files or add dropped settings snapshots as jobs.

accepts_multiple() bool[source]

Return True to be called per-folder on multi-item drops.

apply(path: pathlib.Path, screen) None[source]

Wire path into screen (set src, populate settings, etc.).

can_accept(path: pathlib.Path) bool[source]

Return True if path (folder OR file) is usable as-is.

error_message(path: pathlib.Path) str[source]

Human-friendly explanation for why path can’t be used.

class spacr.qt.dnd_handlers.ClassifyDropHandler[source]

Bases: spacr.qt.dnd.DropHandler

Accept a plate folder with measurements/measurements.db or a folder produced by the annotate step.

apply(path: pathlib.Path, screen) None[source]

Wire path into screen (set src, populate settings, etc.).

can_accept(path: pathlib.Path) bool[source]

Return True if path (folder OR file) is usable as-is.

error_message(path: pathlib.Path) str[source]

Human-friendly explanation for why path can’t be used.

class spacr.qt.dnd_handlers.CoefficientsDropHandler(app_key: str = '')[source]

Bases: LayoutDropHandler

Prediction Profiler: the regression coefficients under results/.

deliver(screen, value: str, target) None[source]

Put value into the screen. Runs on the GUI thread.

Parameters:
  • screen – the screen the drop landed on.

  • value – the resolved path.

  • target – the spacr.chaining.DropTarget it came from, or None for a file the user dropped directly.

kinds[source]
suffixes = ('.csv',)[source]
class spacr.qt.dnd_handlers.ConvertDropHandler[source]

Bases: spacr.qt.dnd.DropHandler

Use a dropped microscopy container or folder as converter input.

apply(path: pathlib.Path, screen) None[source]

Wire path into screen (set src, populate settings, etc.).

can_accept(path: pathlib.Path) bool[source]

Return True if path (folder OR file) is usable as-is.

error_message(path: pathlib.Path) str[source]

Human-friendly explanation for why path can’t be used.

class spacr.qt.dnd_handlers.DataManagerDropHandler(app_key: str = '')[source]

Bases: ProjectFolderDropHandler

Data Manager: set the project, then measure it.

deliver(screen, value: str, target) None[source]

Put value into the screen. Runs on the GUI thread.

Parameters:
  • screen – the screen the drop landed on.

  • value – the resolved path.

  • target – the spacr.chaining.DropTarget it came from, or None for a file the user dropped directly.

class spacr.qt.dnd_handlers.DatabaseDropHandler[source]

Bases: spacr.qt.dnd.DropHandler

Open a dropped measurements database in the Database Browser.

apply(path: pathlib.Path, screen) None[source]

Wire path into screen (set src, populate settings, etc.).

can_accept(path: pathlib.Path) bool[source]

Return True if path (folder OR file) is usable as-is.

error_message(path: pathlib.Path) str[source]

Human-friendly explanation for why path can’t be used.

class spacr.qt.dnd_handlers.EvaluationBundleDropHandler(app_key: str = '')[source]

Bases: LayoutDropHandler

Classifier Evaluation: the run folder holding the evaluation bundle.

apply(path: pathlib.Path, screen) None[source]

Wire path into screen (set src, populate settings, etc.).

can_accept(path: pathlib.Path) bool[source]

Return True if path (folder OR file) is usable as-is.

deliver(screen, value: str, target) None[source]

Put value into the screen. Runs on the GUI thread.

Parameters:
  • screen – the screen the drop landed on.

  • value – the resolved path.

  • target – the spacr.chaining.DropTarget it came from, or None for a file the user dropped directly.

form = 'root'[source]
kinds[source]
suffixes = ('.json', '.csv')[source]
class spacr.qt.dnd_handlers.ExternalMasksDropHandler[source]

Bases: spacr.qt.dnd.DropHandler

Append mixed intensity images and external label masks to the mapper.

accepts_multiple() bool[source]

Return True to be called per-folder on multi-item drops.

apply(path: pathlib.Path, screen) None[source]

Wire path into screen (set src, populate settings, etc.).

can_accept(path: pathlib.Path) bool[source]

Return True if path (folder OR file) is usable as-is.

error_message(path: pathlib.Path) str[source]

Human-friendly explanation for why path can’t be used.

class spacr.qt.dnd_handlers.ForeignProjectDropHandler[source]

Bases: spacr.qt.dnd.DropHandler

Populate Import Project from image folders, tables and mapping files.

accepts_multiple() bool[source]

Return True to be called per-folder on multi-item drops.

apply(path: pathlib.Path, screen) None[source]

Wire path into screen (set src, populate settings, etc.).

can_accept(path: pathlib.Path) bool[source]

Return True if path (folder OR file) is usable as-is.

error_message(path: pathlib.Path) str[source]

Human-friendly explanation for why path can’t be used.

class spacr.qt.dnd_handlers.ImageFieldsDropHandler[source]

Bases: spacr.qt.dnd.DropHandler

Image-folder input shared by Model Compare.

apply(path: pathlib.Path, screen) None[source]

Wire path into screen (set src, populate settings, etc.).

can_accept(path: pathlib.Path) bool[source]

Return True if path (folder OR file) is usable as-is.

error_message(path: pathlib.Path) str[source]

Human-friendly explanation for why path can’t be used.

class spacr.qt.dnd_handlers.LabelMaskDropHandler(app_key: str = '')[source]

Bases: LayoutDropHandler

Curate and Napari Bridge: one label mask, from wherever you drop.

Dropping the project resolves masks/; a folder of masks is not one mask, so the file is asked for rather than guessed at.

deliver(screen, value: str, target) None[source]

Put value into the screen. Runs on the GUI thread.

Parameters:
  • screen – the screen the drop landed on.

  • value – the resolved path.

  • target – the spacr.chaining.DropTarget it came from, or None for a file the user dropped directly.

kinds[source]
suffixes = ('.tif', '.tiff', '.png', '.npy')[source]
class spacr.qt.dnd_handlers.LayerStackDropHandler(app_key: str = '')[source]

Bases: LabelMaskDropHandler

Layer Viewer: the dropped array, added as an image or as labels.

A viewer stacks layers, so a multi-drop of an image and its mask lands as two layers rather than as the first one.

accepts_multiple() bool[source]

Return True to be called per-folder on multi-item drops.

deliver(screen, value: str, target) None[source]

Put value into the screen. Runs on the GUI thread.

Parameters:
  • screen – the screen the drop landed on.

  • value – the resolved path.

  • target – the spacr.chaining.DropTarget it came from, or None for a file the user dropped directly.

suffixes = ('.tif', '.tiff', '.png', '.jpg', '.jpeg', '.npy', '.npz')[source]
class spacr.qt.dnd_handlers.LayoutDropHandler(app_key: str = '')[source]

Bases: spacr.qt.dnd.DropHandler

Drop policy for a screen that names what it wants, not where it is.

A subclass says two things: the vocabulary terms it consumes (kinds, from spacr.ports.ALL_KINDS) and what to do with the answer (deliver()). Everything between — climbing from the dropped path to the project root, asking the registry, falling back to the declared layout, noticing that the answer is ambiguous — is spacr.chaining.resolve_drop().

Ambiguity is routed through the machinery spacr.qt.dnd already has: an ambiguous drop reports can_accept() is False and returns the candidates from suggest_alternatives(), so the user gets the “did you mean…” chooser and apply() is called again with their answer. A drop that resolves to nothing reports spacr.chaining.DropResolution.reason, which is spacr.ports.check_ready()’s own sentence about what is missing.

apply(path: pathlib.Path, screen) None[source]

Wire path into screen (set src, populate settings, etc.).

can_accept(path: pathlib.Path) bool[source]

Return True if path (folder OR file) is usable as-is.

abstract deliver(screen, value: str, target) None[source]

Put value into the screen. Runs on the GUI thread.

Parameters:
  • screen – the screen the drop landed on.

  • value – the resolved path.

  • target – the spacr.chaining.DropTarget it came from, or None for a file the user dropped directly.

error_message(path: pathlib.Path) str[source]

Human-friendly explanation for why path can’t be used.

resolve(path: pathlib.Path)[source]

Return the spacr.chaining.DropResolution for path.

suggest_alternatives(path: pathlib.Path) List[pathlib.Path][source]

When can_accept returns False, return sibling/child folders that WOULD be accepted so the UI can prompt “did you mean…”.

Default: no suggestions.

app_key = 'LayoutDropHandler'[source]
form: str = 'path'[source]
kinds: tuple = ()[source]
label: str = ''[source]
suffixes: tuple = ()[source]
class spacr.qt.dnd_handlers.LineageDropHandler(app_key: str = '')[source]

Bases: TableDropHandler

Lineage: a database path field and one load.

deliver(screen, value: str, target) None[source]

Put value into the screen. Runs on the GUI thread.

Parameters:
  • screen – the screen the drop landed on.

  • value – the resolved path.

  • target – the spacr.chaining.DropTarget it came from, or None for a file the user dropped directly.

class spacr.qt.dnd_handlers.MakeMasksDropHandler[source]

Bases: spacr.qt.dnd.DropHandler

Accept a folder with images (or image+mask pairs).

apply(path: pathlib.Path, screen) None[source]

Wire path into screen (set src, populate settings, etc.).

can_accept(path: pathlib.Path) bool[source]

Return True if path (folder OR file) is usable as-is.

error_message(path: pathlib.Path) str[source]

Human-friendly explanation for why path can’t be used.

suggest_alternatives(path: pathlib.Path) List[pathlib.Path][source]

When can_accept returns False, return sibling/child folders that WOULD be accepted so the UI can prompt “did you mean…”.

Default: no suggestions.

class spacr.qt.dnd_handlers.MapBarcodesDropHandler[source]

Bases: spacr.qt.dnd.DropHandler

Accept a FASTQ file (.fastq/.fastq.gz) or a folder containing one.

apply(path: pathlib.Path, screen) None[source]

Wire path into screen (set src, populate settings, etc.).

can_accept(path: pathlib.Path) bool[source]

Return True if path (folder OR file) is usable as-is.

error_message(path: pathlib.Path) str[source]

Human-friendly explanation for why path can’t be used.

class spacr.qt.dnd_handlers.MaskDropHandler[source]

Bases: spacr.qt.dnd.DropHandler

Accept a folder of raw microscopy images and preview its filename regex parse. Multi-drop is supported.

accepts_multiple() bool[source]

Return True to be called per-folder on multi-item drops.

apply(path: pathlib.Path, screen) None[source]

Wire path into screen (set src, populate settings, etc.).

can_accept(path: pathlib.Path) bool[source]

Return True if path (folder OR file) is usable as-is.

error_message(path: pathlib.Path) str[source]

Human-friendly explanation for why path can’t be used.

suggest_alternatives(path: pathlib.Path) List[pathlib.Path][source]

When can_accept returns False, return sibling/child folders that WOULD be accepted so the UI can prompt “did you mean…”.

Default: no suggestions.

class spacr.qt.dnd_handlers.MeasureDropHandler[source]

Bases: spacr.qt.dnd.DropHandler

Accept the merged folder produced by the mask module, or a parent folder that contains one.

apply(path: pathlib.Path, screen) None[source]

Wire path into screen (set src, populate settings, etc.).

can_accept(path: pathlib.Path) bool[source]

Return True if path (folder OR file) is usable as-is.

error_message(path: pathlib.Path) str[source]

Human-friendly explanation for why path can’t be used.

suggest_alternatives(path: pathlib.Path) List[pathlib.Path][source]

When can_accept returns False, return sibling/child folders that WOULD be accepted so the UI can prompt “did you mean…”.

Default: no suggestions.

class spacr.qt.dnd_handlers.MeasurementsDropHandler[source]

Bases: spacr.qt.dnd.DropHandler

Accept a database, its measurements folder, or its plate folder.

apply(path: pathlib.Path, screen) None[source]

Wire path into screen (set src, populate settings, etc.).

can_accept(path: pathlib.Path) bool[source]

Return True if path (folder OR file) is usable as-is.

error_message(path: pathlib.Path) str[source]

Human-friendly explanation for why path can’t be used.

class spacr.qt.dnd_handlers.MethodsSourcesDropHandler(app_key: str = '')[source]

Bases: LayoutDropHandler

Methods & Results: fill whichever of its four source fields fits.

accepts_multiple() bool[source]

Return True to be called per-folder on multi-item drops.

apply(path: pathlib.Path, screen) None[source]

Wire path into screen (set src, populate settings, etc.).

can_accept(path: pathlib.Path) bool[source]

Return True if path (folder OR file) is usable as-is.

form = 'root'[source]
class spacr.qt.dnd_handlers.ModelZooDropHandler[source]

Bases: spacr.qt.dnd.DropHandler

Scan checkpoints, or use image-only folders as benchmark fields.

apply(path: pathlib.Path, screen) None[source]

Wire path into screen (set src, populate settings, etc.).

can_accept(path: pathlib.Path) bool[source]

Return True if path (folder OR file) is usable as-is.

error_message(path: pathlib.Path) str[source]

Human-friendly explanation for why path can’t be used.

class spacr.qt.dnd_handlers.PlateQueueDropHandler[source]

Bases: spacr.qt.dnd.DropHandler

Queue plate folders that carry spaCR settings snapshots.

accepts_multiple() bool[source]

Return True to be called per-folder on multi-item drops.

apply(path: pathlib.Path, screen) None[source]

Wire path into screen (set src, populate settings, etc.).

can_accept(path: pathlib.Path) bool[source]

Return True if path (folder OR file) is usable as-is.

error_message(path: pathlib.Path) str[source]

Human-friendly explanation for why path can’t be used.

class spacr.qt.dnd_handlers.ProjectFolderDropHandler(app_key: str = '')[source]

Bases: LayoutDropHandler

A screen that takes a whole project, wherever inside it you drop.

kinds is empty on purpose: there is no port for “the project”, and inventing one would put it in the module graph. The layout walk still happens — dropping <plate>/measurements/measurements.db on the pipeline graph opens <plate>.

can_accept(path: pathlib.Path) bool[source]

Return True if path (folder OR file) is usable as-is.

deliver(screen, value: str, target) None[source]

Put value into the screen. Runs on the GUI thread.

Parameters:
  • screen – the screen the drop landed on.

  • value – the resolved path.

  • target – the spacr.chaining.DropTarget it came from, or None for a file the user dropped directly.

form = 'root'[source]
setters: tuple = ('load_project', 'set_project', 'set_source', 'add_root', 'set_src')[source]
class spacr.qt.dnd_handlers.ProjectRootsDropHandler(app_key: str = '')[source]

Bases: ProjectFolderDropHandler

Project Browser: several folders at once, each becoming a root.

accepts_multiple() bool[source]

Return True to be called per-folder on multi-item drops.

deliver(screen, value: str, target) None[source]

Put value into the screen. Runs on the GUI thread.

Parameters:
  • screen – the screen the drop landed on.

  • value – the resolved path.

  • target – the spacr.chaining.DropTarget it came from, or None for a file the user dropped directly.

setters = ('add_root',)[source]
class spacr.qt.dnd_handlers.ReportDropHandler[source]

Bases: spacr.qt.dnd.DropHandler

Accept a completed spaCR run folder and scan its report inputs.

apply(path: pathlib.Path, screen) None[source]

Wire path into screen (set src, populate settings, etc.).

can_accept(path: pathlib.Path) bool[source]

Return True if path (folder OR file) is usable as-is.

error_message(path: pathlib.Path) str[source]

Human-friendly explanation for why path can’t be used.

class spacr.qt.dnd_handlers.ResultsDatabaseDropHandler[source]

Bases: DatabaseDropHandler

Database input for Plate Viewer and Annotator Agreement.

apply(path: pathlib.Path, screen) None[source]

Wire path into screen (set src, populate settings, etc.).

class spacr.qt.dnd_handlers.ResultsFolderDropHandler(app_key: str = '')[source]

Bases: LayoutDropHandler

Hit List: the results/ folder a regression wrote.

deliver(screen, value: str, target) None[source]

Put value into the screen. Runs on the GUI thread.

Parameters:
  • screen – the screen the drop landed on.

  • value – the resolved path.

  • target – the spacr.chaining.DropTarget it came from, or None for a file the user dropped directly.

kinds[source]
suffixes = ()[source]
class spacr.qt.dnd_handlers.RunHistoryDropHandler(app_key: str = '')[source]

Bases: ProjectFolderDropHandler

Run History: select the run a dropped run folder belongs to.

apply(path: pathlib.Path, screen) None[source]

Wire path into screen (set src, populate settings, etc.).

can_accept(path: pathlib.Path) bool[source]

Return True if path (folder OR file) is usable as-is.

setters = ('select_run',)[source]
class spacr.qt.dnd_handlers.ScatterTableDropHandler(app_key: str = '')[source]

Bases: TableDropHandler

Image Scatter: a path field, a table picker, then the read.

deliver(screen, value: str, target) None[source]

Put value into the screen. Runs on the GUI thread.

Parameters:
  • screen – the screen the drop landed on.

  • value – the resolved path.

  • target – the spacr.chaining.DropTarget it came from, or None for a file the user dropped directly.

class spacr.qt.dnd_handlers.SourceDropHandler[source]

Bases: spacr.qt.dnd.DropHandler

General source-path policy for modules without a narrower contract.

Every standard AppScreen has a src field. Accepting a real directory here gives newer and less-specialised modules drag-and-drop support automatically instead of requiring a registry edit for every screen. A dropped file is only accepted for known data extensions and is normalised to its containing directory.

Where the module declares ports, the value comes from spacr.chaining.resolve_drop() — the same answer auto-chaining would fill the field with — so dropping <plate>/measurements and letting the chain fill src cannot produce two different strings. A module with no declaration keeps the plain normalisation below, which is all there is to go on.

apply(path: pathlib.Path, screen) None[source]

Wire path into screen (set src, populate settings, etc.).

can_accept(path: pathlib.Path) bool[source]

Return True if path (folder OR file) is usable as-is.

error_message(path: pathlib.Path) str[source]

Human-friendly explanation for why path can’t be used.

class spacr.qt.dnd_handlers.SubmissionSettingsDropHandler(app_key: str = '')[source]

Bases: LayoutDropHandler

Distributed Jobs: a settings snapshot to submit, or the plate with one.

apply(path: pathlib.Path, screen) None[source]

Wire path into screen (set src, populate settings, etc.).

can_accept(path: pathlib.Path) bool[source]

Return True if path (folder OR file) is usable as-is.

error_message(path: pathlib.Path) str[source]

Human-friendly explanation for why path can’t be used.

suffixes = ('.csv', '.json', '.yaml', '.yml')[source]
class spacr.qt.dnd_handlers.TableDropHandler(app_key: str = '')[source]

Bases: LayoutDropHandler

A screen that reads one table: the explorers, the plotters, the gates.

Drop the project and it finds measurements/measurements.db; drop the database and it uses it; drop a CSV and it reads that. When the database holds more than one table the table is asked rather than taken — load_path picks the first one silently, which is fine for a file dialog where the user chose the file and wrong for a drop where they chose a folder.

deliver(screen, value: str, target) None[source]

Put value into the screen. Runs on the GUI thread.

Parameters:
  • screen – the screen the drop landed on.

  • value – the resolved path.

  • target – the spacr.chaining.DropTarget it came from, or None for a file the user dropped directly.

form = 'path'[source]
kinds[source]
suffixes = ('.db', '.sqlite', '.sqlite3', '.csv', '.tsv', '.parquet', '.txt')[source]
class spacr.qt.dnd_handlers.TrainingRunsDropHandler[source]

Bases: spacr.qt.dnd.DropHandler

Accept a directory and asynchronously scan it for training runs.

apply(path: pathlib.Path, screen) None[source]

Wire path into screen (set src, populate settings, etc.).

can_accept(path: pathlib.Path) bool[source]

Return True if path (folder OR file) is usable as-is.

error_message(path: pathlib.Path) str[source]

Human-friendly explanation for why path can’t be used.

spacr.qt.dnd_handlers.active_scan_jobs(screen) int[source]

How many folder-scan threads screen still owns.

spacr.qt.dnd_handlers.get_handler(app_key: str) spacr.qt.dnd.DropHandler[source]

Return a fresh DropHandler for app_key.

Falls back to SourceDropHandler so every conventional AppScreen can at least receive its source folder.

spacr.qt.dnd_handlers.scan_folder_structure(path) Dict[str, Any][source]

Walk a dropped folder ONCE and return the folder-metadata report.

Worker-safe: plain data in, plain data out, nothing Qt. The single walk is the point. This replaced three walks of the same tree — detect_folder_metadata did one, plan_folder_extraction did another and called detect_folder_metadata again for a third — all on the GUI thread, all inside the drop event.

The probe is pulled off the same lazy generator the planner then drains, so a folder whose layout is not recognisable costs 30 files, not a traversal.

Returns:

{"labels": (...), "rows": [...], "error": ""}. Empty labels means no folder layout was recognised and there is nothing to report.

spacr.qt.dnd_handlers.scan_is_busy(screen) bool[source]

True while a dropped folder is still being walked for screen.

spacr.qt.dnd_handlers.scan_mask_folder(path, sample: int = 20) Dict[str, Any][source]

List the top level of a dropped folder once. Worker-safe.

Returns the filenames the regex preview samples plus the total image count the report quotes. Both used to come from two separate listings of the same directory, taken on the GUI thread.

spacr.qt.dnd_handlers.table_names(path: pathlib.Path) List[str][source]

Return the tables in a SQLite file, or [] for anything else.

One sqlite_master query; the table screens make the same one when they load. Kept here so the drop can ask which table rather than let load_path take the first one silently.

Opened read-only, and through a quoted URI: a folder with a ? or a # in its name would otherwise have everything after it read as query parameters, and the open would fail on a database that is perfectly fine.

spacr.qt.dnd_handlers.LOG[source]
spacr.qt.dnd_handlers.NO_DROP_TARGET: Dict[str, str][source]