scenex.app#
scenex.app
#
Application and GUI framework abstraction layer.
This module provides a unified interface for managing GUI applications across different frameworks (Qt, WxPython, Jupyter) and rendering backends. It handles the event loop, window creation, and platform-specific details, allowing scenex to work seamlessly across desktop and web environments.
The app abstraction decouples scenex from specific GUI frameworks, making it possible to switch between Qt widgets, WxPython windows, or Jupyter notebook outputs without changing your visualization code.
Main Components
- App: Abstract base class for GUI applications
- GuiFrontend: Enumeration of supported GUI frameworks (Qt, WxPython, Jupyter)
- app(): Factory function that returns the active application instance
- determine_app(): Auto-detect which GUI framework to use
Supported Frontends
Qt (PyQt6, PySide6) WxPython Jupyter
Examples:
The app is typically created automatically by scenex.show() and/or scenex.run():
>>> import scenex as snx
>>> import numpy as np
>>> # Create a scenex scene
>>> my_array = np.random.rand(100, 100).astype(np.float32)
>>> my_scene = snx.Scene(children=[snx.Image(data=my_array)])
>>> # Showing the scene creates the app if needed
>>> snx.show(my_scene)
Canvas(...)
>>> snx.run() # Starts the event loop
But it CAN be useful to access the app instance directly. For example, it can be useful to ask the app to process any pending events:
>>> from scenex.app import app
>>> app().process_events()
Notes
This module is designed to be cleanly extractable to a separate library if needed. It fully encapsulates GUI framework logic and event loop management.
See Also
scenex.run : Convenience function to start the event loop scenex.show : Creates and displays visualizations
Modules:
-
events–Event system for handling user input and interaction.
Classes:
-
App–Base class for GUI application wrappers.
-
CursorType–Enumeration of standard cursor types for canvas interaction.
-
GuiFrontend–Enum of available GUI frontends.
Functions:
-
app–Get the active GUI application instance.
-
determine_app–Determine which GUI backend to use for the application.
-
ensure_main_thread–Decorator that ensures a function is called in the main GUI thread.
App
#
Bases: ABC
flowchart TD
scenex.app.App[App]
click scenex.app.App href "" "scenex.app.App"
Base class for GUI application wrappers.
App provides an abstract interface for integrating scenex with different GUI frameworks (Qt, WxPython, Jupyter). Each GUI backend implements this interface to provide framework-specific application lifecycle management, event handling, and threading operations.
The App class is typically accessed via the app() function, which automatically
determines and initializes the appropriate backend based on the environment and
available GUI frameworks.
Notes
This is an abstract base class. Concrete implementations are provided by backend-specific subclasses (QtAppWrap, WxAppWrap, JupyterAppWrap).
See Also
app : Function to get the active application instance GuiFrontend : Enumeration of available GUI backends determine_app : Function to determine which GUI backend to use
Methods:
-
call_in_main_thread–Schedule a function to be called in the main GUI thread.
-
call_later–Schedule a function to be called after a delay.
-
create_app–Create the application instance, if not already created.
-
get_executor–Return an executor for running tasks in background threads.
-
install_event_filter–Install an event filter on a native widget to forward events to a handler.
-
process_events–Yields the current thread to process all pending GUI events.
-
run–Start the application event loop.
-
set_cursor–Set the cursor on a native canvas widget.
-
show–Show or hide a native canvas widget.
call_in_main_thread
#
Schedule a function to be called in the main GUI thread.
Many GUI frameworks require that widget operations occur on the main thread. This method safely schedules a function call on the main thread and returns a Future that will contain the result.
Parameters:
-
(func#Callable[P, T]) –The function to call.
-
(*args#args, default:()) –Positional arguments to pass to func.
-
(**kwargs#kwargs, default:{}) –Keyword arguments to pass to func.
Returns:
-
Future[T]–A Future object that will contain the function's return value once the call completes.
Notes
The base implementation executes the function immediately and returns a completed Future. Subclasses should override this to provide thread-safe execution.
Source code in src/scenex/app/_auto.py
306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 | |
call_later
abstractmethod
#
Schedule a function to be called after a delay.
Parameters:
-
(msec#int) –Delay in milliseconds before calling the function.
-
(func#Callable[[], None]) –The function to call. Must take no arguments.
Notes
Must be implemented by subclasses.
Source code in src/scenex/app/_auto.py
340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 | |
create_app
abstractmethod
#
create_app() -> Any
Create the application instance, if not already created.
This method initializes the underlying GUI framework's application object (e.g., QApplication for Qt). If an application instance already exists, this method should return the existing instance.
Returns:
-
Any–The backend-specific application object.
Notes
Must be implemented by subclasses.
Source code in src/scenex/app/_auto.py
217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 | |
get_executor
#
get_executor() -> Executor
Return an executor for running tasks in background threads.
Returns:
-
Executor–A concurrent.futures.Executor instance (typically a ThreadPoolExecutor) for running background tasks.
Notes
The default implementation returns a shared ThreadPoolExecutor with 2 workers. Subclasses can override this to provide framework-specific executors.
Source code in src/scenex/app/_auto.py
357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 | |
install_event_filter
abstractmethod
#
Install an event filter on a native widget to forward events to a handler.
Implementations of this method will capture all events given to the native
widget, translate them into scenex events, and call handler with each one.
Parameters:
-
(widget#Any) –The backend-specific native canvas widget.
-
(handler#Callable[[Event], bool]) –A callable that receives each translated scenex event and returns True if the event was handled (stopping further propagation), False otherwise. Typically
model_canvas.handle.
Returns:
-
EventFilter–A handle that can be used to uninstall the event filter.
Notes
Must be implemented by subclasses.
Source code in src/scenex/app/_auto.py
267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 | |
process_events
abstractmethod
#
process_events() -> None
Yields the current thread to process all pending GUI events.
Notes
Must be implemented by subclasses.
Source code in src/scenex/app/_auto.py
296 297 298 299 300 301 302 303 304 | |
run
abstractmethod
#
run() -> None
Start the application event loop.
This method enters the GUI framework's main event loop, which processes user input, window events, and other GUI operations. The method blocks until the application is closed.
Notes
Must be implemented by subclasses.
Source code in src/scenex/app/_auto.py
236 237 238 239 240 241 242 243 244 245 246 247 248 | |
set_cursor
abstractmethod
#
set_cursor(native_widget: Any, cursor: CursorType) -> None
Set the cursor on a native canvas widget.
Backends override this to translate the abstract cursor into native form.
Parameters:
-
(native_widget#Any) –The backend-specific native canvas widget.
-
(cursor#CursorType) –The type of cursor to set.
Source code in src/scenex/app/_auto.py
389 390 391 392 393 394 395 396 397 398 399 400 401 402 | |
show
abstractmethod
#
show(native_widget: Any, visible: bool) -> None
Show or hide a native canvas widget.
Parameters:
-
(native_widget#Any) –The backend-specific native canvas widget to show or hide.
-
(visible#bool) –True to show the canvas window, False to hide it.
Notes
Must be implemented by subclasses.
Source code in src/scenex/app/_auto.py
250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 | |
CursorType
#
Bases: Enum
flowchart TD
scenex.app.CursorType[CursorType]
click scenex.app.CursorType href "" "scenex.app.CursorType"
Enumeration of standard cursor types for canvas interaction.
CursorType provides platform-independent cursor shapes that can be set on canvases to indicate different interaction modes or states. Each cursor type is mapped to the appropriate platform-specific cursor by the GUI backend.
Attributes:
-
DEFAULT(int) –The standard arrow cursor, typically used for normal selection and interaction.
-
CROSS(int) –A crosshair cursor, useful for precise positioning or drawing operations.
-
V_ARROW(int) –A vertical resize arrow cursor, indicating vertical resizing capability.
-
H_ARROW(int) –A horizontal resize arrow cursor, indicating horizontal resizing capability.
-
ALL_ARROW(int) –A multi-directional arrow cursor, indicating omnidirectional movement.
-
BDIAG_ARROW(int) –A diagonal resize arrow cursor (backward diagonal), for diagonal resizing.
-
FDIAG_ARROW(int) –A diagonal resize arrow cursor (forward diagonal), for diagonal resizing.
Examples:
Set a crosshair cursor during drawing mode:
>>> import scenex as snx
>>> canvas = snx.Canvas()
>>> snx.set_cursor(canvas, CursorType.CROSS)
Restore default cursor after operation:
>>> snx.set_cursor(canvas, CursorType.DEFAULT)
See Also
snx.set_cursor : Function to set cursor on a canvas
GuiFrontend
#
app
#
app() -> App
Get the active GUI application instance.
Returns the singleton App instance for the current process, creating and
initializing it if necessary. The GUI backend is determined automatically
using determine_app().
This function should be used whenever you need to interact with the GUI application, such as running the event loop, showing windows, or scheduling thread-safe operations.
Returns:
-
App–The active App instance wrapping the GUI backend.
Examples:
Get the app and run the event loop:
>>> app().run()
See Also
determine_app : Function that selects which GUI backend to use GuiFrontend : Enumeration of available backends App : Base class defining the application interface
Source code in src/scenex/app/_auto.py
551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 | |
determine_app
#
determine_app() -> GuiFrontend
Determine which GUI backend to use for the application.
This function selects the appropriate GUI framework backend through a three-tier strategy:
- Explicit request: If the SCENEX_APP_BACKEND environment variable is set, that backend is used (e.g., "qt", "wx", "jupyter").
- Running application: If a GUI application is already running in the process (detected via framework imports), that backend is used.
- Available backend: Try importing each backend in a predefined order until one succeeds.
Returns:
-
GuiFrontend–The determined GUI backend to use.
Raises:
-
ValueError–If the SCENEX_APP_BACKEND environment variable is set to an invalid value.
-
RuntimeError–If no GUI backend can be found or loaded.
Examples:
Let the function auto-detect the backend:
>>> backend = determine_app()
Force a specific backend via environment variable:
>>> import os
>>> os.environ["SCENEX_APP_BACKEND"] = "qt"
>>> backend = determine_app() # Will use Qt
See Also
app : Get the active App instance using the determined backend GuiFrontend : Enumeration of available backends
Source code in src/scenex/app/_auto.py
476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 | |
ensure_main_thread
#
Decorator that ensures a function is called in the main GUI thread.
This decorator wraps a function so that when called, it is automatically scheduled to run on the main GUI thread rather than the caller's thread. This is essential for GUI operations that must occur on the main thread.
Parameters:
Returns:
-
Callable[P, Future[T]]–A wrapped version of func that returns a Future instead of the direct result. The Future will contain the function's return value once the call completes on the main thread.
Examples:
Ensure a GUI operation runs on the main thread:
>>> @ensure_main_thread
... def update_widget(value: int) -> None:
... # Update some GUI widget with the given value
... pass
>>> future = update_widget(42) # Returns immediately with Future
>>> result = future.result() # Block until completion if needed
See Also
App.call_in_main_thread : Underlying method for thread-safe calls
Source code in src/scenex/app/_auto.py
434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 | |