This commit is contained in:
i
2026-04-22 16:29:23 +08:00
parent fe8d7f9b21
commit bc328260b7
2 changed files with 44 additions and 0 deletions
+1
View File
@@ -12,6 +12,7 @@
| **批量 D2C** | 对 Orbbec Viewer 导出的深度图批量软件对齐,无需连接相机 | | **批量 D2C** | 对 Orbbec Viewer 导出的深度图批量软件对齐,无需连接相机 |
| **双算法支持** | 正向投影 + Splat 填充 / 逆向投影(SDK 同等),可实时切换预览 | | **双算法支持** | 正向投影 + Splat 填充 / 逆向投影(SDK 同等),可实时切换预览 |
| **自动参数获取** | 从相机实时提取内外参,自动保存为 JSON | | **自动参数获取** | 从相机实时提取内外参,自动保存为 JSON |
| **热插拔监听** | 自动监听设备插入/拔出并刷新设备列表,无需手动反复点击刷新 |
| **分辨率自适应** | 支持字体缩放(0.8× ~ 2.0×),适配不同 DPI 屏幕 | | **分辨率自适应** | 支持字体缩放(0.8× ~ 2.0×),适配不同 DPI 屏幕 |
--- ---
+43
View File
@@ -1222,6 +1222,8 @@ class _Toast(QLabel):
# ───────────────────────────────────────────────────────────────── # ─────────────────────────────────────────────────────────────────
class MainWindow(QMainWindow): class MainWindow(QMainWindow):
hotplug_changed = pyqtSignal()
def __init__(self): def __init__(self):
super().__init__() super().__init__()
_title = "Orbbec 数据采集 & D2C" _title = "Orbbec 数据采集 & D2C"
@@ -1235,6 +1237,8 @@ class MainWindow(QMainWindow):
self._batch_worker: BatchD2CWorker | None = None self._batch_worker: BatchD2CWorker | None = None
self._fetch_worker: FetchParamsWorker | None = None self._fetch_worker: FetchParamsWorker | None = None
self._refresh_worker: RefreshDevicesWorker | None = None self._refresh_worker: RefreshDevicesWorker | None = None
self._ob_context = None
self._hotplug_pending = False
self._session_dir: Path | None = None self._session_dir: Path | None = None
self._params_filename = "camera_params.json" self._params_filename = "camera_params.json"
self._color_profiles_data: list[dict] = [] self._color_profiles_data: list[dict] = []
@@ -1244,6 +1248,8 @@ class MainWindow(QMainWindow):
self._build_ui() self._build_ui()
# toast 覆盖在 central widget 上 # toast 覆盖在 central widget 上
self._toast = _Toast(self.centralWidget()) self._toast = _Toast(self.centralWidget())
self.hotplug_changed.connect(self._schedule_hotplug_refresh)
self._setup_hotplug_monitor()
# ───────────────────────────────── # ─────────────────────────────────
# UI Construction # UI Construction
@@ -1709,6 +1715,37 @@ class MainWindow(QMainWindow):
# Device Refresh # Device Refresh
# ───────────────────────────────── # ─────────────────────────────────
def _setup_hotplug_monitor(self):
try:
from pyorbbecsdk import Context
except Exception as exc:
self._append_d2c_log(f"[热插拔] 监听不可用:{exc}")
return
try:
self._ob_context = Context()
self._ob_context.set_device_changed_callback(self._on_device_changed_callback)
self._append_d2c_log("[热插拔] 已启用设备插拔监听。")
except Exception as exc:
self._ob_context = None
self._append_d2c_log(f"[热插拔] 启用失败:{exc}")
def _on_device_changed_callback(self, removed_list, added_list):
self.hotplug_changed.emit()
def _schedule_hotplug_refresh(self):
if self._hotplug_pending:
return
self._hotplug_pending = True
QTimer.singleShot(350, self._run_hotplug_refresh)
def _run_hotplug_refresh(self):
if getattr(self, "_refreshing", False):
QTimer.singleShot(400, self._run_hotplug_refresh)
return
self._hotplug_pending = False
self._append_d2c_log("[热插拔] 检测到设备变化,自动刷新中…")
self._refresh_devices()
def _refresh_devices(self): def _refresh_devices(self):
if getattr(self, '_refreshing', False): if getattr(self, '_refreshing', False):
return return
@@ -2132,6 +2169,12 @@ class MainWindow(QMainWindow):
# ───────────────────────────────── # ─────────────────────────────────
def closeEvent(self, event): def closeEvent(self, event):
if self._ob_context is not None:
try:
self._ob_context.set_device_changed_callback(None)
except Exception:
pass
self._ob_context = None
self._stop_stream() self._stop_stream()
# 等待所有后台 worker 真正退出,防止 QThread destroyed while running # 等待所有后台 worker 真正退出,防止 QThread destroyed while running
for w in list(self._stopping_workers): for w in list(self._stopping_workers):