spacr.qt.app¶
QApplication bootstrap + MainWindow.
launch(argv) is the public entry point called by spacr-qt and
python -m spacr.qt.
Classes¶
Top-level window: sidebar + stacked screens + status bar. |
|
The application's navigation dock. |
Functions¶
|
Whether |
|
How finished |
|
The dock's TOP-LEVEL rows: Home's tiles, then Help, in that order. |
|
|
|
|
|
|
|
app key → stage, for every app in |
|
Install the registered dialog event filters on a Qt application. |
|
Put the spaceout fractal behind |
|
Bootstrap QApplication and show the main window. |
|
Build the Home page exactly as the running app builds it. |
|
Add one app to the registry. The seam a new module registers through. |
|
Import and return the pipeline callable app |
|
The factory registered for |
|
|
|
The |
|
Sort key placing |
|
The |
|
Remove app |
|
Registry rows allowed by the Alpha/Beta visibility preferences. |
Module Contents¶
- class spacr.qt.app.MainWindow(initial_app: str | None = None)[source]¶
Bases:
PySide6.QtWidgets.QMainWindowTop-level window: sidebar + stacked screens + status bar.
- Parameters:
initial_app – optional app key to navigate to on show; when omitted the window opens on the Home startup page.
Build the main window: the dock slot, the screen stack and the status bar.
The window is frameless and the menu bar is what you drag it by. Its first backing store is filled with the splash colour so the compositor cannot expose stale desktop pixels before anything has drawn – deliberately without
WA_OpaquePaintEvent, which is a promise to paint every pixel that this window cannot keep once the application stylesheet clearsautoFillBackgroundagain. Claiming it left whatever was already on screen underneath, and transparent children drew on top: overlapping text in the corner, and flicker on every text surface over the animated backdrop.The dock slot exists in every dock mode, because a
QMainWindow’s central widget cannot be swapped without re-parenting the stack, and re-parenting a stack holding live screens is how locking the dock would cost you the screen you were looking at.- Parameters:
initial_app – the module to open on startup;
Noneopens Home.
- __init__(initial_app: str | None = None)[source]¶
Build the main window: the dock slot, the screen stack and the status bar.
The window is frameless and the menu bar is what you drag it by. Its first backing store is filled with the splash colour so the compositor cannot expose stale desktop pixels before anything has drawn – deliberately without
WA_OpaquePaintEvent, which is a promise to paint every pixel that this window cannot keep once the application stylesheet clearsautoFillBackgroundagain. Claiming it left whatever was already on screen underneath, and transparent children drew on top: overlapping text in the corner, and flicker on every text surface over the animated backdrop.The dock slot exists in every dock mode, because a
QMainWindow’s central widget cannot be swapped without re-parenting the stack, and re-parenting a stack holding live screens is how locking the dock would cost you the screen you were looking at.- Parameters:
initial_app – the module to open on startup;
Noneopens Home.
- apply_dock_mode(mode: str | None = None) None[source]¶
Put the app list where the preference says it goes.
Two modes, one
Sidebarobject:lockedthe sidebar sits in the window’s dock slot, where itis an ordinary column in the layout: it never animates, and because it is a LAYOUT MEMBER rather than an overlay the page beside it is narrower by the dock’s width instead of running underneath it.
hiddenthe slot stays empty. The “All apps” action isdisabled with a tooltip that says where to turn it back on — a control that silently does nothing is worse than one that is greyed out.
THERE IS NO REVEAL-ON-HOVER MODE. It slid the dock in OVER the page, so the home screen’s module tiles sat underneath it and did not move aside, and it needed a second container behind the dock’s own panel to be legible over whatever it covered. Both were the complaint. The drawer object still exists and is kept closed and disabled, because it also carries the keyboard path that the “All apps” action uses.
Idempotent, and safe to call before the menu exists.
- changeEvent(event)[source]¶
Re-lay the menu bar when the window state changes.
A menu opens where the BAR SAYS its action is. Going fullscreen resizes the bar and its corner widget in one step, and a menu opened before the layout has caught up is placed against the previous action rectangle – which is how pressing spaCR drops a menu under Help.
- Parameters:
event – the change event; only a window-state change re-lays the menu bar.
- closeEvent(event)[source]¶
Cooperatively drain analysis and UI workers before destruction.
- Parameters:
event – the close event; ignored, leaving the window open, when a worker or an application screen does not stop, otherwise passed to the base class, and the application quits if it is accepted.
- dock_mode() str[source]¶
The user’s dock preference —
auto/locked/hidden.Read through here rather than inlined so a headless build, or one with an unwritable settings file, still gets the default rather than an exception during
__init__.
- eventFilter(watched, event)[source]¶
Handle frameless-window menu-bar drag and double-click gestures.
Teardown can invalidate the Qt menu bar while events are still queued. This filter returns
Falseinstead of allowing that condition to escape through PySide’s callback boundary.- Parameters:
watched – Qt object receiving the event.
event – Qt event delivered to the main window’s filter.
- Returns:
Truewhen a menu-bar mouse gesture is consumed; otherwiseFalse.
- keyPressEvent(event) None[source]¶
Up and Down change the spaceout zoom rate; Ctrl+R starts over.
- Parameters:
event – the key press; its key and Ctrl modifier are read, and keys the backdrop does not take are passed to the base class.
- open_module(app_key: str) str[source]¶
Navigate to the screen that carries
app_key, folded or not.A module folded into a host keeps its key everywhere a key is saved: a run journal, the force-restart record,
spacr-qt <app>in somebody’s shell history. That key no longer names a screen, and navigating to it anyway BUILDS one – an orphan page with no sidebar row, no tile and no way back to it, which is the second front door the fold exists to remove.So the key is resolved to the host that took it over, and the fold it names is switched on: asking for Timelapse is asking for what the tracking switch reveals, not for mask generation with the switch off.
- Parameters:
app_key – the key that was asked for.
- Returns:
the app key actually opened.
Give every menu-bar action an explicit macOS role. Idempotent.
Called at the end of
_build_menu_barAND again fromspacr.qt.shortcuts.install, becauserecipes,walkthroughandfeature_dictionaryall add to Help afterwards. Each of those also pins its own – defence in depth – but a central re-sweep is what makes a module added later safe without its author knowing this problem exists.
- rebuild_app_screen(key: str, values=None) None[source]¶
Build
key’s screen again, carryingvaluesacross.- Parameters:
key – the app whose screen is to be rebuilt.
values – settings to apply to the new screen.
WHY A WHOLE SCREEN. Which settings a form holds depends on a few of its own values – the organelle count, and whether an object’s channel names a plane – so a committed change to one of those means a different form, not a changed one. Rebuilding is the same path every module open already takes.
The old screen is dropped from the cache and destroyed, so the new one is built from scratch rather than reusing widgets that belong to a shape that no longer applies.
- refresh_theme() None[source]¶
Rebuild everything preferences cannot update through QSS alone.
Three things do not follow a
setStyleSheetcall: the Home tiles set sizes/margins from the font scale in Python, every QIcon baked its pixmap at the theme in force when it was built, and the dock’s mode and the page’s opacity are layout decisions rather than colours. Called after the Preferences dialog closes, and found by duck-typing fromspacr.qt.preferences.apply_preferences_to_app()so a preference change from anywhere reaches the widgets.
- resizeEvent(event)[source]¶
Keep the loading screen covering the whole window, and erase the menu bar’s old band.
EVERY RESIZE, not only a state change. Dragging an edge moves the corner buttons without changing the window state, so
changeEventnever fires – and the marks are redrawn at their new x over the old ones. That is the “sometimes” in the report: it is not intermittent, it is every resize that is not a fullscreen toggle.- Parameters:
event – the resize event, passed to the base class; the new geometry is read from the window itself.
- resume_after_restart() str[source]¶
Reopen the module a Force restart saved. Returns its key, or “”.
TAKEN, NOT READ:
restart_state.takedeletes the state as it hands it over, so a crash on the way back up cannot leave spaCR reopening the same wedged module on every launch afterwards – which would turn one bad afternoon into a permanently broken installation.THE SETTINGS ARE APPLIED, THE RUN IS NOT STARTED. 142 C: the runs do not come back, only the configuration, and starting one unasked would be the opposite of what somebody who just force-restarted wants.
- show_preferences_on(tab: str = '', label: str = '') bool[source]¶
Open Preferences, on a named tab, with a named row marked.
The route the Help search field takes for a preference result: the dialog carries nine tabs and a result that opened it on whichever one it happened to start with has answered half the question.
Found by OBJECT NAME rather than by tab index or caption. An index moves whenever a tab is added, and a caption is translated – a Korean interface would have matched nothing. Every page sets its own
PreferencesTab*name, andtools/build_help_search_index.pyreads those same names out of this dialog’s source, so the two ends of the hand-off are the same string by construction.- Parameters:
tab – the page’s object name, e.g.
"PreferencesTabTheme";""opens the dialog as it opens from the menu.label – the row caption to mark;
""marks nothing.
- Returns:
True when the named tab was found and shown.
- stylesheet_roots()[source]¶
The widgets that carry the application sheet, instead of me.
WHY NOT THE WINDOW. Setting a stylesheet on a window repolishes every descendant, and a session that has opened four modules owns 8,002 widgets of which 7,595 are inside module screens – ONE of which is on screen. Measured on this box, four modules open, alternating dark and light:
the whole window 945 ms first, ~1,479 ms steady chrome + the visible page 300 ms first, ~310 ms steady
WHAT IS IN THE LIST, and the shape is not the obvious one. The chrome is 407 widgets and only TWO of them are reachable from the central widget – the dock, the sidebar and the status strip hang off the window itself. An implementation that walked the central widget would leave 405 unstyled and look almost right, which is why
tests/qt/test_every_widget_wears_the_current_theme.pydoes exactly that on purpose and asserts it is caught.So: every direct child of the window except the central widget, every direct child of the central widget except the stack, and the stack’s CURRENT page. The pages that are not showing are marked instead, and sheeted on their own
showEventbefore they are painted.
- toggle_app_drawer() None[source]¶
Put keyboard focus on the app dock. The menu and Ctrl+Shift+A path.
THE DOCK NO LONGER SLIDES, so there is nothing to open: it is a permanent column when the preference is
locked. What the action still has to do is get a keyboard user INTO it, because a column you can only reach by tabbing through the page is one that is hard to reach at all.A no-op when the dock is hidden – the user asked for it not to be there, and a shortcut that overrules a preference is a bug. The action is disabled in that mode anyway, so this is the second half of a belt and braces rather than the only guard.
- toggle_fullscreen(*_args) bool[source]¶
Enter or leave true fullscreen. Returns whether it is now full.
- class spacr.qt.app.Sidebar(parent=None)[source]¶
Bases:
spacr.qt.widgets.dock.DockThe application’s navigation dock.
The behaviour lives in
spacr.qt.widgets.dock.Dock, rewritten on 2026-09-03 after four rounds of fixes to the old one had not settled it. This is only the binding to the registry, and it keeps the old NAME because the theme’s#Sidebarrules, the tutorial highlighter, the home-variant generators and the tests all reach the dock by it.What used to be here was 1,095 lines of
_DockRowandSidebar: a translucent slab painted inpaintEvent(the “black box” four commits chased), a per-row icon-size model that relaid the column out under the pointer, a name drawn only while hovered, and a folded second level with its own expand state. See the module docstring ofspacr.qt.widgets.dockfor what replaced each one.- Parameters:
parent – parent widget; ownership only.
Build the dock with Home above the registered module rows.
- Parameters:
parent – parent widget, or
None.
- spacr.qt.app.app_is_visible(key: str) bool[source]¶
Whether
keyshould appear in module navigation.Preferences are imported lazily so this registry remains safe for packaging and headless callers. If preferences cannot be read, preserve the historical all-modules-visible behaviour.
NOT A TILE CHECK. This answers “is the user allowed to reach this module”, which is the maturity preference and nothing else. A folded module is still reachable – from its host’s button, from Help, and from the command palette – so it is still VISIBLE; it just has no tile. Use
tiled_apps()for the tile question.This function did briefly answer both, and the command palette is what caught it: filtering
TILELESS_APPSout here took nine modules out of Ctrl+K, so the folds removed a door instead of moving one. Two questions, two functions.- Parameters:
key – the app key whose stage is checked against the maturity preference.
- spacr.qt.app.app_stage(key: str) str[source]¶
How finished
keyis — one ofSTAGES.Unknown keys read as stable rather than raising: a stage is an annotation on an app, and an app with no annotation is one nobody has flagged.
- Parameters:
key – the app key looked up in
APP_STAGE; unknown keys giveSTAGE_STABLE.
- spacr.qt.app.dock_rows() List[Tuple[str, str, str, str]][source]¶
The dock’s TOP-LEVEL rows: Home’s tiles, then Help, in that order.
ONE RULE: a row is a dock host if, and only if, Home draws a tile for it. Everything else in the registry reaches the dock as an indented child under its fold host, or under one of the Help modules, and nothing appears twice.
THIS USED TO RETURN ALL OF
APPS, and the result was a dock that did not match the Home screen: modules belonging to Help sat outside it, and modules that should have been nested under a host were listed flat. The dock is meant to mimic the screen module tiles … everything else is nested and in help dropdown.”Measured before the change: 36 top-level dock rows against 19 Home tiles, and NINE keys drawn twice –
convert,external_masks,investigate_hit,layer_viewer,lineage,plate_view,profiler,tabulateandtrain_compareeach had a top-level row AND an indented row under the host they fold into. A module that appears in two places in the same column is a module the reader cannot learn the location of.tiled_apps()is the authority rather than a second hand-written list, so the dock cannot drift from Home again: promoting a module to a tile gives it a dock row, and folding one takes its dock row away, both without touching this function. That is the same lesson_HELP_MODULESalready encodes below – 330’s note records one bug from a duplicated list and the retired-section map records another.WHY HELP IS NOT A REAL SECTION: see
SECTION_HELP. A section is Home’s categorisation and every Help module is tileless, so Help would be a tab with nothing on it. The dock has no such constraint.The dock walks these rows in order and starts a new heading whenever the section changes, so grouping IS ordering here – a row out of place draws its heading a second time.
- spacr.qt.app.folded_children() Dict[str, Tuple[str, ...]][source]¶
host key -> the module keys folded onto its masthead.ONE MAPPING, read from the hosts themselves, so the dock, the menu bar and the fold strips cannot disagree about what belongs where. Each host declares its own
FOLDED_APPS; that tuple is the truth and this only collects them.The dock and the spaCR menu both draw the nested structure from this, showing a folded module one level below the host it belongs to.
Never raises: a host whose module cannot be imported contributes nothing, because a navigation aid must not be able to stop the window being built.
- spacr.qt.app.home_bands(apps: List[Tuple[str, str, str, str]] | None = None) List[Tuple[str, List[Tuple[str, str, str, str]]]][source]¶
(band, rows)for the Home tab, inSECTIONSorder.The same grouping the tabs use — every app once, under what it is about. Home is the “all of it” view and each later tab is a filter of it, which is only true while both read this one table.
Bands with no apps are dropped rather than drawn empty. None are, today; the guard is what stops a heading appearing over nothing the day a section’s last app is retired.
- spacr.qt.app.home_categories(apps: List[Tuple[str, str, str, str]] | None = None) List[Tuple[str, List[str]]][source]¶
(section, [app key])for every tab after Home, in tab order.Computed rather than written down, so a section cannot acquire a tab it has no apps for or lose one it does.
- spacr.qt.app.home_stages() dict[source]¶
app key → stage, for every app in
APPS.What
make_home_page()hands the Home page, so the tiles and the legend colour from the same table this module owns and the widget still knows nothing about what a stage means.
- spacr.qt.app.install_the_dialog_filters(app) tuple[str, ...][source]¶
Install the registered dialog event filters on a Qt application.
Installers are idempotent and isolated: a failure in one filter does not prevent the remaining filters from being installed.
- Parameters:
app – the Qt application each filter installer is called with.
- Returns:
Names of the filters installed successfully.
- spacr.qt.app.install_the_spaceout_fractal(screen) bool[source]¶
Put the spaceout fractal behind
screen, if this is spaceout.- Parameters:
screen – the widget the fractal is parented to and sized to fill; an event filter on it keeps the fractal following it.
- Returns:
True when it was installed, so the caller knows to skip the ordinary ambient backdrop. False in every normal launch – which is what keeps the mode hidden – and false rather than raising when the fractal cannot be built, so a machine that cannot draw it still gets the animation it always had.
The settings come from Preferences, which shows them only under spaceout, so one place decides both what is offered and what is drawn.
- spacr.qt.app.launch(argv: list[str] | None = None) int[source]¶
Bootstrap QApplication and show the main window.
- spacr.qt.app.make_home_page(parent=None)[source]¶
Build the Home page exactly as the running app builds it.
The grouping, the stages, the notes and the icon provider are four arguments that have to agree, and a test that assembles its own HomePage is testing a page that does not ship — which is the exact class of bug #16i was: Home grouped by one table and the tabs by another. One constructor call, used by
MainWindowand by the suite.
- spacr.qt.app.register_app(key: str, name: str, desc: str, section: str, *, factory=None, stage: str | None = None, title: str | None = None, intro: str | None = None, cli_note: str | None = None, api_module: str | None = None, entry: str | None = None, defaults_module: str | None = None, translations: Tuple[str, ...] | None = None) Tuple[str, str, str, str][source]¶
Add one app to the registry. The seam a new module registers through.
Call it at import time from the module that owns the app:
from spacr.qt.app import register_app, SECTION_EXPLORE, STAGE_ALPHA register_app("graph_builder", "Graph Builder", "Drag columns onto x / y / colour / facet", SECTION_EXPLORE, factory=make_screen, stage=STAGE_ALPHA)
The first four arguments put a tile on Home and a row in the sidebar. The keyword arguments after
stageare what make that tile a working app: they are the app’s strings, given ONCE here, and fanned out into the tables that used to need a hand-edit each — seeAPP_META.- Parameters:
key – stable app id. Load-bearing —
bridge,cli,validate, the drag-and-drop handlers,settings_modeland saved user state all key off it, so it is chosen once and never renamed. Must be unique across built-ins and plugins.name – display name; the sidebar row, tile and menu entry.
desc – one-line summary; the tooltip and status tip.
section – one of
SECTION_ORDER. A section with no apps has no tab, so registering the first app into a new section is what makes that section appear.factory – optional zero-argument callable returning the app’s
QWidgetscreen. It may declareapp_keyand/orhostkeyword parameters —hostis theMainWindow, for a screen that has signals to connect — and is given whichever of the two it accepts. Omit it and the app gets the generic settings-drivenAppScreen, like every pipeline module.stage – optional
STAGESmember. Omitted means stable, which is also what deleting the entry later means.title – header shown at the top of the app’s own screen. Defaults to
name; give it only when the screen wants the longer form (“Illumination Correction” over a tile that reads “Illumination”). Reachesapp_screen.APP_TITLES.intro – the paragraph beside that header — what the module does, in a sentence or two. Defaults to
desc. Reachesapp_screen.APP_INTROS.cli_note – for an app with NO headless path: one sentence saying so and what to do instead. Reaches
cli.INTERACTIVE_ONLY, which is whatspacr-run <key>prints instead of “unknown module”. Mutually exclusive withentryin spirit — an app is one or the other.api_module – dotted-or-slashed module path under the generated API docs (“qt/layer_viewer”), for the ⓘ link beside the settings. Reaches
settings_model._APP_API_MODULE.entry –
"module:function"of the callable the Run button runs. Resolved lazily byregistered_entry()and consulted byspacr.qt.bridge.resolve_pipeline_entry(); without it the Run button answers “Not runnable”.defaults_module – the module whose import calls
spacr.settings.register_defaults()for this key.settings_model.resolve_default_settingsimports it before asking whether the key has registered defaults — otherwise a module that registers its settings at import has no settings panel until something else happens to import it, and the app opens on an empty form. Imported on demand, so registering an app costs no numpy/pandas/torch at startup.translations – the display
namein the nine non-English UI languages, inspacr.qt.i18n.LANGUAGESorder. Reachesi18n._ROWSand its catalogs.
- Returns:
the row that was appended, so a caller can keep it.
- Raises:
ValueError – on a duplicate key, an unknown section, an unknown stage or an empty name/description.
TypeError – if
factoryis not callable.
- spacr.qt.app.registered_entry(key: str)[source]¶
Import and return the pipeline callable app
keyregistered.Nonewhen the app registered noentry=, which is what an interactive-only app (its own screen, no Run button) does.spacr.qt.bridge.resolve_pipeline_entry()consults this after its own built-in chain, soregister_app(..., entry="mod:func")is all a new pipeline app needs for its Run button to run something. Imported here, on demand, rather than at registration: registering an app must not drag numpy, torch or pandas into a process that only wanted to draw a sidebar.- Parameters:
key – the app key whose
entrymetadata ('module:function') is imported.
- spacr.qt.app.registered_factory(key: str)[source]¶
The factory registered for
key, orNone.A declared app is registered with a
LazyScreenFactorystanding in for the real callable, and this is where the stand-in ends: asking for the factory imports the screen and returns the module’s own function.That is deliberate, and it is what makes laziness invisible to everything downstream.
_call_screen_factory()decides whether to passapp_keyandhostby reading the factory’s signature, and a stand-in’s signature is its own, not the real one’s; a test that asserts the registered factoryisthe module’s function would likewise be comparing against the wrapper. Resolving here means neither ever sees one.The resolved callable replaces the stand-in in
APP_FACTORIES, so the import happens once even if the screen is opened and closed all afternoon. A stand-in whose module fails to import is left in place andNoneis returned: the app falls back to the generic settings screen rather than taking the window down.- Parameters:
key – the app key looked up in
APP_FACTORIES.
- spacr.qt.app.registered_metadata(field: str) dict[source]¶
{app key: value}for oneAPP_METAfield, empty ones dropped.The PULL half of the seam. A side table calls this at the end of its own import to absorb every app that registered before it existed:
_app = sys.modules.get("spacr.qt.app") if _app is not None: for _key, _value in _app.registered_metadata("title").items(): APP_TITLES.setdefault(_key, _value)
setdefault, not assignment: a table’s own hand-written entry is the more specific one and wins.- Parameters:
field – the
APP_METAfield to collect, such as'title'.
- spacr.qt.app.section_members(section: str, apps: List[Tuple[str, str, str, str]] | None = None) List[Tuple[str, str, str, str]][source]¶
The
APPSrows a category’s tab shows, in registry order.TILELESS APPS ARE NOT MEMBERS. This is what the tab DRAWS and what its label COUNTS, so a module with no tile must be out of both – otherwise the label reads “Results & QC (7)” over three tiles, which is a count of something the user cannot see.
An explicit
appslist is filtered too. A caller passing its own rows is asking “which of these belong to this section”, and a tileless one does not belong to any tab whichever list it arrives in.- Parameters:
section – the category name, compared with the fourth element of each
APPSrow.
- spacr.qt.app.tile_sort_key(row: Tuple[str, str, str, str]) Tuple[int, int][source]¶
Sort key placing
rowwhereSECTION_TILE_ORDERsays.- Parameters:
row – an
APPSrow.- Returns:
(section index, position in that section). An unlisted key sorts after every listed one, keeping registry order among the unlisted by virtue of Python’s stable sort.
- spacr.qt.app.tiled_apps(apps: List[Tuple[str, str, str, str]] | None = None) List[Tuple[str, str, str, str]][source]¶
The
APPSrows that get a TILE, in registry order.APPSis what EXISTS; this is what Home DRAWS. The two stopped being the same thing when modules began folding into hosts – a folded module keeps its registry row (it still has a screen, an icon, a section and a key to navigate to) and loses only its tile, because it is now reached from a button on its host or from the Help menu.Anything asking “what does the user see on Home”, “how many tiles are in this band”, or “does this tile’s label fit” wants this. Anything asking “can this key be navigated to”, “does this app have artwork”, or “does every app have a screen” wants
APPS– a folded module must still answer yes to all three.An app registered with the alpha gate has no tile while Preferences > Show alpha features is off: Home does not draw it, so nothing that counts or lists Home’s tiles may count it either.
- spacr.qt.app.unregister_app(key: str) bool[source]¶
Remove app
keyfrom the registry.Trueif there was one.The counterpart to
register_app(), for a plugin that unloads and for tests that must not leak a registration into the next one — a stray row inAPPSis a stray tile, a stray sidebar entry and a stray Ctrl+N binding for every test that follows.- Parameters:
key – the app key to remove, converted to a string.
Nested helpers¶
- MainWindow.__init__._finish_installer_onboarding()¶
Show the installer consent, then start the tour after it closes.
spacr/qt/app.py:3010
- MainWindow._retry_screen_backdrop.again() None¶
Try the backdrop once more, if the screen is still alive.
spacr/qt/app.py:6633
- MainWindow._show_about._line(html, size, *, muted=False, weight=400, gap=0)¶
One centred line of the About box, at the given size.
spacr/qt/app.py:4125
- MainWindow._start_a_sample_project.open_it(key)¶
Open the actual module, including its page inside a host screen.
spacr/qt/app.py:5833
- _collect_paint_diagnostics.failed(what)¶
Log the exception being handled and name it in
errors.spacr/qt/app.py:2428
- _declared_folds._as_string(node, _depth=0)¶
The string an AST node stands for, or
Noneif it is not one.Resolves a literal, a module constant, and another module’s constant read the same way rather than by importing it.
_depthbounds that indirection so a constant defined in terms of itself stops instead of recursing.spacr/qt/app.py:1640
- _import_the_data_libraries_off_the_gui_thread._work() None¶
Import each library, logging rather than raising a failure.
spacr/qt/app.py:387
- _start_icon_prewarm.warm()¶
Fill the icon caches, and never let a bad file reach the GUI.
spacr/qt/app.py:7294
- _start_settings_prewarm._warm_the_settings_imports()¶
Import each module, logging rather than raising a failure.
spacr/qt/app.py:7156
- _start_settings_prewarm.warm()¶
Import the remaining settings dependencies without building widgets.
spacr/qt/app.py:7150
- launch._drain_ai()¶
Stop every job runner before Qt starts destroying widgets.
Connected to
aboutToQuit, which fires however the application exits. See the comment below for why this covers every runner and not only the consoles.spacr/qt/app.py:7522