""" motion_capture/camera_panel.py CameraPanel for AddDeviceDialog — shows selected camera info and builds a CameraDevice when the user clicks "Add Device". Camera discovery and simulation toggle are handled by AddDeviceDialog. """ from __future__ import annotations from PyQt6.QtCore import QThread, pyqtSignal from PyQt6.QtWidgets import QLabel, QVBoxLayout, QWidget class CameraScanThread(QThread): cameras_found = pyqtSignal(list) # list of (index: int, label: str) def run(self): results = [] try: import cv2 for i in range(6): cap = cv2.VideoCapture(i) if cap.isOpened(): ret, _ = cap.read() if ret: w = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) h = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) results.append((i, f"Camera {i} ({w}×{h})")) cap.release() except ImportError: pass self.cameras_found.emit(results) class CameraPanel(QWidget): """Config panel for Camera device in AddDeviceDialog.""" def __init__(self): super().__init__() self._selected_index: int = 0 self._simulate: bool = False lay = QVBoxLayout(self) lay.setContentsMargins(0, 4, 0, 4) lay.setSpacing(8) self._selected_lbl = QLabel("No camera selected — scan above and click a camera") self._selected_lbl.setObjectName("traceSource") self._selected_lbl.setWordWrap(True) lay.addWidget(self._selected_lbl) note = QLabel( "Requires OpenCV: pip install opencv-python\n" "Use Simulation mode if no camera is available." ) note.setObjectName("traceSource") note.setWordWrap(True) lay.addWidget(note) lay.addStretch() def is_valid(self) -> bool: return True def set_simulate(self, simulate: bool): self._simulate = simulate def set_camera_index(self, index: int): self._selected_index = index self._selected_lbl.setText(f"Selected: Camera {index}") def build_device(self, device_id: str): from device import CameraDevice return CameraDevice( device_id=device_id, camera_index=self._selected_index, simulate=self._simulate, )