Skip to content

Refactor camera config dialog and reduce code duplication#46

Merged
deruyter92 merged 6 commits intocy/upgrade-basler-backendfrom
cy/improve-camera-loaders
Feb 13, 2026
Merged

Refactor camera config dialog and reduce code duplication#46
deruyter92 merged 6 commits intocy/upgrade-basler-backendfrom
cy/improve-camera-loaders

Conversation

@C-Achard
Copy link

This pull request introduces significant improvements to camera preview management and frame processing in the GUI, as well as code organization and test updates. The main changes are the introduction of a new preview.py module to manage camera preview state, refactoring of frame processing utilities into static methods, and creation of new worker classes for camera loading. Several imports and references are updated to reflect the reorganized module structure, and tests are updated to use the new preview state management.

Camera preview state management and utilities:

  • Added new dlclivegui/gui/camera_config/preview.py module, introducing PreviewState enum and PreviewSession dataclass to manage the preview lifecycle and associated runtime objects. Also added utility functions for frame rotation, cropping, resizing, and conversion to display pixmap.
  • Refactored frame processing methods (apply_rotation, apply_crop, apply_resize, ensure_color_bgr, ensure_color_rgb, to_display_pixmap) into static methods of MultiCameraController, centralizing frame handling logic and making them reusable. [1] [2] [3] [4] [5]

Camera loader and detection workers:

  • Added dlclivegui/gui/camera_config/loaders.py with background worker classes (DetectCamerasWorker, CameraProbeWorker, CameraLoadWorker) to handle camera detection, probing, and loading in the GUI, improving responsiveness and separation of concerns.

Code organization and import updates:

  • Moved CameraConfigDialog and related logic into dlclivegui/gui/camera_config/camera_config_dialog.py and updated all relevant imports in both source and test files to use the new path. [1] [2] [3] [4]

Testing improvements:

  • Updated GUI tests to use the new PreviewState and PreviewSession for asserting preview activity and backend/timer state, replacing legacy booleans and attributes. [1] [2] [3] [4]

Other enhancements:

  • Added a static check_diff method to CameraSettings for comparing camera configuration changes.
  • Added camera identity utility functions (apply_detected_identity, camera_identity_key) to dlclivegui/cameras/factory.py for persisting and retrieving stable camera identifiers.
  • Improved documentation and comments on fast-start probing in the Basler backend.
  • Minor import fixes for Qt image classes.

Move camera worker and preview state logic into a new module (dlclivegui/gui/camera_loaders.py) and refactor the CameraConfigDialog to use it. Added DetectCamerasWorker, CameraProbeWorker, CameraLoadWorker, PreviewState enum and PreviewSession dataclass to centralize loader/backend/timer intent. Removed the embedded worker classes from camera_config_dialog.py and replaced multiple booleans/flags with a single PreviewSession, an epoch-based signal invalidation mechanism, coalesced preview restarts, and unified scan/preview UI syncing. Also adjusted loader signal handlers to be epoch-aware, simplified start/stop flows, and made small docstring/comment tweaks in basler_backend.py regarding fast_start.
Move camera configuration code into a dedicated gui/camera_config package and extract UI construction into a new ui_blocks module. Renamed camera_config_dialog.py and camera_loaders.py to camera_config/camera_config_dialog.py and camera_config/loaders.py respectively, replaced the large _setup_ui implementation with setup_camera_config_dialog_ui(dlg) from ui_blocks.py, and added ui_blocks.py to build the dialog UI. Updated relative imports in __init__.py, main_window.py, and affected modules/tests to the new paths. This refactor improves modularity and keeps the dialog file focused on logic rather than bulky widget construction.
Move camera identity utilities into cameras.factory (apply_detected_identity, camera_identity_key) and add CameraSettings.check_diff for concise settings diffs. Major refactor of CameraConfigDialog: reorganize UI/state helpers, probe/preview lifecycle, auto-apply pending edits, improved scan/probe cancellation and dialog reject handling, duplicate-camera checks, add reorder/add/remove safety, and split preview helpers into a new preview module; also remove unused cv2 import. These changes centralize identity handling, improve preview & probe UX, and add safer settings application and logging. Tests updated to match the new contracts.
Add a unified _on_close_cleanup and closeEvent to ensure preview/worker shutdown and UI reset on dialog close/cancel. Make cleanup idempotent with a _cleanup_done guard, shorten worker wait times to reduce UI freeze, and defensively reset scan UI widgets. Connect scan cancel button handler. Initialize _multi_camera_settings fallback, tighten type annotations, and note eventFilter UI assignments. Refactor form/apply flow to build a new CameraSettings model, compute diffs, replace the working camera entry and update the active list item (apply now returns a truthy value). Call _reconcile_fps_from_backend when loading settings, remove exc_info from a loader error log, and invoke cleanup before accepting the dialog. These changes improve robustness during shutdown and reduce UI hangs.
Move preview state and session datatypes into preview.py and refactor low-level image ops into MultiCameraController static methods. preview.py now delegates rotation, crop, resize and pixmap conversion to MultiCameraController (with proper type hints and QTimer usage). loaders.py removes duplicate PreviewState/PreviewSession definitions and cleans imports. camera_config_dialog uses getattr to safely read backend.actual_fps and updates imports to match the refactor. MultiCameraController gains apply_rotation/apply_crop/apply_resize/ensure_color_* and to_display_pixmap utilities (default: no upscale when resizing).
Adapt camera config GUI tests to the refactored preview API: import PreviewState and replace checks against legacy dialog attributes (_loader, _preview_active, _preview_backend, _preview_timer) with dialog._preview.loader, dialog._preview.state (using PreviewState.*), dialog._preview.backend, and dialog._preview.timer. Update waitUntil conditions and assertions across test_cam_dialog_e2e.py to reflect the new preview state machine and object structure.
@C-Achard C-Achard self-assigned this Feb 13, 2026
@C-Achard C-Achard added enhancement New feature or request camera Related to cameras and camera backends gui Related to the GUI itself : windows and fields bugs, UI, UX, ... labels Feb 13, 2026
@C-Achard C-Achard requested a review from deruyter92 February 13, 2026 13:53
@deruyter92 deruyter92 merged commit 48faa41 into cy/upgrade-basler-backend Feb 13, 2026
@C-Achard C-Achard mentioned this pull request Feb 16, 2026
15 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

camera Related to cameras and camera backends enhancement New feature or request gui Related to the GUI itself : windows and fields bugs, UI, UX, ...

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

Comments