fix open 3d cannot work in linux

This commit is contained in:
ykcheungab
2026-06-29 10:47:46 +08:00
parent 04a4df3303
commit 4cc1027cc8
2 changed files with 106 additions and 16 deletions
+100 -10
View File
@@ -147,7 +147,7 @@ class FingerDashboardWindow(QMainWindow):
root_layout.addWidget(h_splitter) root_layout.addWidget(h_splitter)
self.resize(layout.window_width, layout.window_height) self.resize(*self._target_window_size())
QTimer.singleShot(0, self._apply_panel_layout) QTimer.singleShot(0, self._apply_panel_layout)
def _set_log_panel_visible(self, visible: bool) -> None: def _set_log_panel_visible(self, visible: bool) -> None:
@@ -157,7 +157,8 @@ class FingerDashboardWindow(QMainWindow):
def _apply_panel_layout(self) -> None: def _apply_panel_layout(self) -> None:
setup = self.layout.panel_setup setup = self.layout.panel_setup
column_height = self.layout.charts_column_height_px() scale = self._layout_scale_factor()
column_height = self._scaled_top_row_height(scale)
charts_slot = self.layout.top_slot("charts") charts_slot = self.layout.top_slot("charts")
log_slot = setup.log_panel log_slot = setup.log_panel
@@ -165,10 +166,18 @@ class FingerDashboardWindow(QMainWindow):
if not slot.enabled: if not slot.enabled:
continue continue
if slot.id in ("mesh", "arrows"): if slot.id in ("mesh", "arrows"):
self._panel_widgets[slot.id].set_fixed_size(slot.width_px, column_height) self._panel_widgets[slot.id].set_fixed_size(
self._scaled_px(slot.width_px, scale),
column_height,
)
elif slot.id == "settings": elif slot.id == "settings":
settings_height = slot.height_px if slot.height_px > 0 else column_height settings_height = (
self.settings_panel.set_panel_size(slot.width_px, settings_height) self._scaled_px(slot.height_px, scale) if slot.height_px > 0 else column_height
)
self.settings_panel.set_panel_size(
self._scaled_px(slot.width_px, scale),
settings_height,
)
if ( if (
self._log_panel_visible self._log_panel_visible
@@ -176,15 +185,96 @@ class FingerDashboardWindow(QMainWindow):
and log_slot.height_px > 0 and log_slot.height_px > 0
): ):
self.log_widget.show() self.log_widget.show()
self.log_widget.setFixedHeight(log_slot.height_px) log_height = self._scaled_px(log_slot.height_px, scale)
self.force_charts.set_panel_size(charts_slot.width_px, charts_slot.height_px) charts_height = self._scaled_px(charts_slot.height_px, scale)
self.charts_column.setSizes([charts_slot.height_px, log_slot.height_px]) self.log_widget.setFixedHeight(log_height)
self.force_charts.set_panel_size(
self._scaled_px(charts_slot.width_px, scale),
charts_height,
)
self.charts_column.setSizes([charts_height, log_height])
else: else:
self.log_widget.hide() self.log_widget.hide()
self.force_charts.set_panel_size(charts_slot.width_px, column_height) self.force_charts.set_panel_size(
self._scaled_px(charts_slot.width_px, scale),
column_height,
)
self.charts_column.setSizes([column_height, 0]) self.charts_column.setSizes([column_height, 0])
self.h_splitter.setSizes(list(top_row_splitter_sizes(self.layout))) self.h_splitter.setSizes(
[self._scaled_px(slot.width_px, scale) for slot in setup.top_row.slots if slot.enabled]
)
def _target_window_size(self) -> tuple[int, int]:
"""Match the top-level window to the fixed panel layout.
The packaged Windows build can use different style metrics than a dev run,
so sizing only from hard-coded window dimensions may stretch or compress the
fixed-width panels. Derive the initial size from the actual panel layout and
current splitter handle widths instead.
"""
layout = self.layout
enabled_slots = [slot for slot in layout.panel_setup.top_row.slots if slot.enabled]
margins = self.centralWidget().layout().contentsMargins()
width = sum(slot.width_px for slot in enabled_slots)
width += max(len(enabled_slots) - 1, 0) * self.h_splitter.handleWidth()
width += margins.left() + margins.right()
height = layout.charts_column_height_px()
if (
self._log_panel_visible
and layout.panel_setup.log_panel.enabled
and layout.panel_setup.log_panel.height_px > 0
):
height += self.charts_column.handleWidth()
height += margins.top() + margins.bottom()
return max(layout.window_width, width), max(layout.window_height, height)
def _layout_scale_factor(self) -> float:
"""Uniformly scale the dashboard to fit the available content area.
Only scale up when the user has explicitly maximized/fullscreened the
window. Keeping normal windowed mode at scale 1 avoids a feedback loop
where larger fixed-size child widgets increase the top-level size hint,
which can make packaged Windows builds keep growing after launch.
"""
if not (self.isMaximized() or self.isFullScreen()):
return 1.0
central = self.centralWidget()
if central is None:
return 1.0
root_layout = central.layout()
if root_layout is None:
return 1.0
margins = root_layout.contentsMargins()
available_width = max(1, central.width() - margins.left() - margins.right())
available_height = max(1, central.height() - margins.top() - margins.bottom())
enabled_slots = [slot for slot in self.layout.panel_setup.top_row.slots if slot.enabled]
base_width = sum(slot.width_px for slot in enabled_slots)
base_width += max(len(enabled_slots) - 1, 0) * self.h_splitter.handleWidth()
base_height = self.layout.charts_column_height_px()
if (
self._log_panel_visible
and self.layout.panel_setup.log_panel.enabled
and self.layout.panel_setup.log_panel.height_px > 0
):
base_height += self.charts_column.handleWidth()
if base_width <= 0 or base_height <= 0:
return 1.0
return min(available_width / base_width, available_height / base_height)
@staticmethod
def _scaled_px(value: int, scale: float) -> int:
return max(int(round(value * scale)), 64)
def _scaled_top_row_height(self, scale: float) -> int:
return self._scaled_px(self.layout.charts_column_height_px(), scale)
def resizeEvent(self, event): def resizeEvent(self, event):
super().resizeEvent(event) super().resizeEvent(event)
+6 -6
View File
@@ -84,9 +84,9 @@ class PanelSetup:
# --- Top strip: mesh | arrows? | charts | settings (edit order and sizes here) --- # --- Top strip: mesh | arrows? | charts | settings (edit order and sizes here) ---
TOP_ROW = PanelRow( TOP_ROW = PanelRow(
slots=( slots=(
PanelSlot("mesh", "3D mesh", width_px=600, height_px=600), PanelSlot("mesh", "3D mesh", width_px=400, height_px=400),
PanelSlot("arrows", "UV Unrolled", width_px=500, height_px=500, enabled=True), PanelSlot("arrows", "UV Unrolled", width_px=400, height_px=400, enabled=True),
PanelSlot("charts", "Force charts", width_px=400, height_px=500), PanelSlot("charts", "Force charts", width_px=300, height_px=400),
PanelSlot("settings", "Settings", width_px=200, height_px=0), PanelSlot("settings", "Settings", width_px=200, height_px=0),
), ),
) )
@@ -223,8 +223,8 @@ class DashboardLayout:
panel_setup: PanelSetup = PANEL_SETUP panel_setup: PanelSetup = PANEL_SETUP
window_title: str = "Orisys Finger Dashboard" window_title: str = "Orisys Finger Dashboard"
window_width: int = 1600 window_width: int = 1300
window_height: int = 620 window_height: int = 520
root_margin_px: int = 6 root_margin_px: int = 6
root_spacing_px: int = 6 root_spacing_px: int = 6
@@ -242,7 +242,7 @@ class DashboardLayout:
# UV arrow panel: min flow magnitude to draw an arrow (display only; not dd02-ov.json contact.flow_threshold) # UV arrow panel: min flow magnitude to draw an arrow (display only; not dd02-ov.json contact.flow_threshold)
arrow_flow_threshold: float = 1.0 arrow_flow_threshold: float = 1.0
# "unrolled" = sensor texture; "pure_color" = solid canvas (tune colors via arrow_canvas_colors) # "unrolled" = sensor texture; "pure_color" = solid canvas (tune colors via arrow_canvas_colors)
arrow_background: ArrowBackground = "unrolled" arrow_background: ArrowBackground = "pure_color"
arrow_canvas_colors: ArrowCanvasColors = ARROW_CANVAS_COLORS arrow_canvas_colors: ArrowCanvasColors = ARROW_CANVAS_COLORS
mesh_lighting: MeshLighting = MESH_LIGHTING mesh_lighting: MeshLighting = MESH_LIGHTING