diff options
| author | Christian Kolset <christian.kolset@gmail.com> | 2026-05-07 14:46:20 -0600 |
|---|---|---|
| committer | Christian Kolset <christian.kolset@gmail.com> | 2026-06-03 09:50:17 -0600 |
| commit | 0a8d42501c1bf168bd852537bb3cd18490fac7ee (patch) | |
| tree | e6e604cb7fc026fed8ffa65ea14929dfabdfbab9 /plugins/motion_capture/plugin.py | |
| parent | 8e5d0aec942fb9c49040fc525f0d697fd24d7c2f (diff) | |
Motion capture: camera selection dropdown
Replace camera index spinbox with a combo listing detected cameras by
name. On Linux enumerates /dev/video* and reads device names from sysfs
(fast, no probing). Fallback probes cv2.VideoCapture indices 0-7 on
other platforms. Simulation entry always appended as last option.
Also adds explicit simulation mode (index -1) to tracker.start() and a
rescan button (⟳) in both the main window and the Settings > Plugins
widget.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Diffstat (limited to 'plugins/motion_capture/plugin.py')
| -rw-r--r-- | plugins/motion_capture/plugin.py | 46 |
1 files changed, 36 insertions, 10 deletions
diff --git a/plugins/motion_capture/plugin.py b/plugins/motion_capture/plugin.py index d4bf497..e5d37c7 100644 --- a/plugins/motion_capture/plugin.py +++ b/plugins/motion_capture/plugin.py @@ -22,7 +22,8 @@ from __future__ import annotations from typing import Any, Dict, List, Optional from PyQt6.QtWidgets import ( - QDoubleSpinBox, QFormLayout, QLabel, QSpinBox, QWidget, + QComboBox, QDoubleSpinBox, QFormLayout, QHBoxLayout, + QLabel, QPushButton, QWidget, ) from plugins.base_plugin import LabPlugin, PluginAction, PluginContext @@ -90,17 +91,26 @@ class MotionCapturePlugin(LabPlugin): ] def get_settings_widget(self) -> Optional[QWidget]: + from tracker import list_cameras w = QWidget() lay = QFormLayout(w) lay.setContentsMargins(0, 4, 0, 4) - self._s_cam = QSpinBox() - self._s_cam.setRange(0, 9) - self._s_cam.setValue( - self._win.get_camera_index() if self._win else 0) - self._s_cam.setObjectName("traceWidthSpin") - self._s_cam.valueChanged.connect(self._sync_cam_to_window) - lay.addRow("Camera index:", self._s_cam) + cam_row = QHBoxLayout() + self._s_cam = QComboBox() + self._s_cam.setObjectName("channelPickerCb") + self._s_cameras: list = [] + self._s_refresh_btn = QPushButton("⟳") + self._s_refresh_btn.setObjectName("configButton") + self._s_refresh_btn.setFixedWidth(28) + self._s_refresh_btn.setToolTip("Rescan cameras") + self._s_refresh_btn.clicked.connect(lambda: self._populate_settings_cam(list_cameras)) + cam_row.addWidget(self._s_cam, 1) + cam_row.addWidget(self._s_refresh_btn) + lay.addRow("Camera:", cam_row) + + self._populate_settings_cam(list_cameras) + self._s_cam.currentIndexChanged.connect(self._sync_cam_to_window) self._s_pxmm = QDoubleSpinBox() self._s_pxmm.setRange(0.01, 100_000) @@ -168,9 +178,25 @@ class MotionCapturePlugin(LabPlugin): if self._toolbar_btn is not None: self._toolbar_btn.setChecked(False) - def _sync_cam_to_window(self, v: int) -> None: + def _populate_settings_cam(self, list_cameras_fn) -> None: + current = self._win.get_camera_index() if self._win else 0 + self._s_cam.blockSignals(True) + self._s_cam.clear() + self._s_cameras = list_cameras_fn() + for _, label in self._s_cameras: + self._s_cam.addItem(label) + for i, (idx, _) in enumerate(self._s_cameras): + if idx == current: + self._s_cam.setCurrentIndex(i) + break + self._s_cam.blockSignals(False) + + def _sync_cam_to_window(self, combo_i: int) -> None: + if not self._s_cameras: + return + idx = self._s_cameras[combo_i][0] if self._win: - self._win.set_camera_index(v) + self._win.set_camera_index(idx) def _sync_pxmm_to_window(self, v: float) -> None: if self._win: |
