设置缩放
This commit is contained in:
@@ -46,7 +46,7 @@ from PyQt5.QtWidgets import (
|
|||||||
QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout,
|
QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout,
|
||||||
QLabel, QPushButton, QLineEdit, QCheckBox, QTabWidget,
|
QLabel, QPushButton, QLineEdit, QCheckBox, QTabWidget,
|
||||||
QComboBox, QFileDialog, QTextEdit, QFrame, QMessageBox,
|
QComboBox, QFileDialog, QTextEdit, QFrame, QMessageBox,
|
||||||
QSizePolicy, QGroupBox,
|
QSizePolicy, QGroupBox, QDialog, QAction,
|
||||||
)
|
)
|
||||||
from PyQt5.QtCore import Qt, QThread, pyqtSignal, QTimer
|
from PyQt5.QtCore import Qt, QThread, pyqtSignal, QTimer
|
||||||
from PyQt5.QtGui import QImage, QPixmap, QFont
|
from PyQt5.QtGui import QImage, QPixmap, QFont
|
||||||
@@ -58,6 +58,128 @@ PARAMS_FILE = "camera_params.json"
|
|||||||
MIN_DEPTH_MM, MAX_DEPTH_MM = 200, 5000
|
MIN_DEPTH_MM, MAX_DEPTH_MM = 200, 5000
|
||||||
_DISCONNECT_TIMEOUTS = 6 # 6 × 500 ms = 3 s 无帧 → 断线
|
_DISCONNECT_TIMEOUTS = 6 # 6 × 500 ms = 3 s 无帧 → 断线
|
||||||
|
|
||||||
|
_UI_SCALE: float = 1.0 # initialized in main() before window creation
|
||||||
|
|
||||||
|
|
||||||
|
def _fs(n: float) -> int:
|
||||||
|
"""Scale a font-size (px or pt) value."""
|
||||||
|
return max(8, int(n * _UI_SCALE))
|
||||||
|
|
||||||
|
|
||||||
|
def _sz(n: float) -> int:
|
||||||
|
"""Scale a UI dimension (px)."""
|
||||||
|
return max(1, int(n * _UI_SCALE))
|
||||||
|
|
||||||
|
|
||||||
|
# ─────────────────────────────────────────────────────────────────
|
||||||
|
# App Settings
|
||||||
|
# ─────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
class AppSettings:
|
||||||
|
_CONFIG_PATH = Path(__file__).parent / "app_settings.json"
|
||||||
|
FONT_SCALE_AUTO = "auto"
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.font_scale: str = self.FONT_SCALE_AUTO
|
||||||
|
self._load()
|
||||||
|
|
||||||
|
def _load(self):
|
||||||
|
if self._CONFIG_PATH.is_file():
|
||||||
|
try:
|
||||||
|
data = json.loads(self._CONFIG_PATH.read_text(encoding="utf-8"))
|
||||||
|
self.font_scale = data.get("font_scale", self.FONT_SCALE_AUTO)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def save(self):
|
||||||
|
self._CONFIG_PATH.write_text(
|
||||||
|
json.dumps({"font_scale": self.font_scale}, ensure_ascii=False, indent=2),
|
||||||
|
encoding="utf-8",
|
||||||
|
)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def compute_auto_scale() -> float:
|
||||||
|
screen = QApplication.primaryScreen()
|
||||||
|
if screen:
|
||||||
|
dpr = screen.devicePixelRatio()
|
||||||
|
return round(max(0.8, min(2.0, dpr)), 2)
|
||||||
|
return 1.0
|
||||||
|
|
||||||
|
def get_scale_factor(self) -> float:
|
||||||
|
if self.font_scale == self.FONT_SCALE_AUTO:
|
||||||
|
return self.compute_auto_scale()
|
||||||
|
try:
|
||||||
|
return float(self.font_scale)
|
||||||
|
except ValueError:
|
||||||
|
return 1.0
|
||||||
|
|
||||||
|
|
||||||
|
# ─────────────────────────────────────────────────────────────────
|
||||||
|
# Settings Dialog
|
||||||
|
# ─────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
class SettingsDialog(QDialog):
|
||||||
|
def __init__(self, settings: "AppSettings", parent=None):
|
||||||
|
super().__init__(parent)
|
||||||
|
self.setWindowTitle("程序设置")
|
||||||
|
self.setFixedSize(_sz(420), _sz(160))
|
||||||
|
self.setWindowFlags(self.windowFlags() & ~Qt.WindowContextHelpButtonHint)
|
||||||
|
self._settings = settings
|
||||||
|
self._build_ui()
|
||||||
|
|
||||||
|
def _build_ui(self):
|
||||||
|
layout = QVBoxLayout(self)
|
||||||
|
layout.setContentsMargins(_sz(16), _sz(14), _sz(16), _sz(14))
|
||||||
|
layout.setSpacing(_sz(10))
|
||||||
|
|
||||||
|
row = QHBoxLayout()
|
||||||
|
lbl = QLabel("字体缩放比例:")
|
||||||
|
lbl.setMinimumWidth(_sz(110))
|
||||||
|
row.addWidget(lbl)
|
||||||
|
|
||||||
|
self._scale_combo = QComboBox()
|
||||||
|
self._scale_combo.setSizeAdjustPolicy(QComboBox.AdjustToContents)
|
||||||
|
for key, label in [
|
||||||
|
("auto", "自动(根据屏幕分辨率和缩放比例)"),
|
||||||
|
("0.8", "0.8× 小"),
|
||||||
|
("1.0", "1.0× 标准"),
|
||||||
|
("1.2", "1.2× 稍大"),
|
||||||
|
("1.5", "1.5× 大"),
|
||||||
|
("2.0", "2.0× 特大"),
|
||||||
|
]:
|
||||||
|
self._scale_combo.addItem(label, key)
|
||||||
|
|
||||||
|
idx = self._scale_combo.findData(self._settings.font_scale)
|
||||||
|
if idx >= 0:
|
||||||
|
self._scale_combo.setCurrentIndex(idx)
|
||||||
|
row.addWidget(self._scale_combo)
|
||||||
|
row.addStretch()
|
||||||
|
layout.addLayout(row)
|
||||||
|
|
||||||
|
auto_val = AppSettings.compute_auto_scale()
|
||||||
|
info = QLabel(f"修改后需重启程序生效。当前屏幕自动比例:×{auto_val:.2f}")
|
||||||
|
info.setStyleSheet(f"color:#888; font-size:{_fs(11)}px;")
|
||||||
|
layout.addWidget(info)
|
||||||
|
|
||||||
|
layout.addStretch()
|
||||||
|
|
||||||
|
btn_row = QHBoxLayout()
|
||||||
|
btn_row.addStretch()
|
||||||
|
ok_btn = QPushButton("确定")
|
||||||
|
ok_btn.setFixedWidth(_sz(80))
|
||||||
|
ok_btn.clicked.connect(self._save_and_close)
|
||||||
|
cancel_btn = QPushButton("取消")
|
||||||
|
cancel_btn.setFixedWidth(_sz(80))
|
||||||
|
cancel_btn.clicked.connect(self.reject)
|
||||||
|
btn_row.addWidget(ok_btn)
|
||||||
|
btn_row.addWidget(cancel_btn)
|
||||||
|
layout.addLayout(btn_row)
|
||||||
|
|
||||||
|
def _save_and_close(self):
|
||||||
|
self._settings.font_scale = self._scale_combo.currentData()
|
||||||
|
self._settings.save()
|
||||||
|
self.accept()
|
||||||
|
|
||||||
|
|
||||||
# ─────────────────────────────────────────────────────────────────
|
# ─────────────────────────────────────────────────────────────────
|
||||||
# Helpers
|
# Helpers
|
||||||
@@ -675,11 +797,11 @@ class _Toast(QLabel):
|
|||||||
self.setAlignment(Qt.AlignCenter)
|
self.setAlignment(Qt.AlignCenter)
|
||||||
self.setAttribute(Qt.WA_TransparentForMouseEvents, True)
|
self.setAttribute(Qt.WA_TransparentForMouseEvents, True)
|
||||||
self.setStyleSheet(
|
self.setStyleSheet(
|
||||||
"background: rgba(30,140,30,210);"
|
f"background: rgba(30,140,30,210);"
|
||||||
"color: white;"
|
f"color: white;"
|
||||||
"border-radius: 10px;"
|
f"border-radius: {_sz(10)}px;"
|
||||||
"font-size: 15px;"
|
f"font-size: {_fs(15)}px;"
|
||||||
"padding: 10px 28px;"
|
f"padding: {_sz(10)}px {_sz(28)}px;"
|
||||||
)
|
)
|
||||||
self._timer = QTimer(self)
|
self._timer = QTimer(self)
|
||||||
self._timer.setSingleShot(True)
|
self._timer.setSingleShot(True)
|
||||||
@@ -691,7 +813,7 @@ class _Toast(QLabel):
|
|||||||
self.adjustSize()
|
self.adjustSize()
|
||||||
p = self.parent()
|
p = self.parent()
|
||||||
self.move((p.width() - self.width()) // 2,
|
self.move((p.width() - self.width()) // 2,
|
||||||
p.height() - self.height() - 70)
|
p.height() - self.height() - _sz(70))
|
||||||
self.raise_()
|
self.raise_()
|
||||||
self.show()
|
self.show()
|
||||||
self._timer.start(ms)
|
self._timer.start(ms)
|
||||||
@@ -700,7 +822,7 @@ class _Toast(QLabel):
|
|||||||
if self.isVisible():
|
if self.isVisible():
|
||||||
p = self.parent()
|
p = self.parent()
|
||||||
self.move((p.width() - self.width()) // 2,
|
self.move((p.width() - self.width()) // 2,
|
||||||
p.height() - self.height() - 70)
|
p.height() - self.height() - _sz(70))
|
||||||
|
|
||||||
|
|
||||||
# ─────────────────────────────────────────────────────────────────
|
# ─────────────────────────────────────────────────────────────────
|
||||||
@@ -714,7 +836,7 @@ class MainWindow(QMainWindow):
|
|||||||
if _COPYRIGHT:
|
if _COPYRIGHT:
|
||||||
_title += f" | © {_COPYRIGHT}"
|
_title += f" | © {_COPYRIGHT}"
|
||||||
self.setWindowTitle(_title)
|
self.setWindowTitle(_title)
|
||||||
self.resize(1300, 860)
|
self.resize(_sz(1300), _sz(860))
|
||||||
|
|
||||||
self._worker: CameraWorker | None = None
|
self._worker: CameraWorker | None = None
|
||||||
self._batch_worker: BatchD2CWorker | None = None
|
self._batch_worker: BatchD2CWorker | None = None
|
||||||
@@ -723,6 +845,7 @@ class MainWindow(QMainWindow):
|
|||||||
self._params_filename = "camera_params.json"
|
self._params_filename = "camera_params.json"
|
||||||
self._color_profiles_data: list[dict] = []
|
self._color_profiles_data: list[dict] = []
|
||||||
self._depth_profiles_data: list[dict] = []
|
self._depth_profiles_data: list[dict] = []
|
||||||
|
self._app_settings = AppSettings()
|
||||||
|
|
||||||
self._build_ui()
|
self._build_ui()
|
||||||
# toast 覆盖在 central widget 上
|
# toast 覆盖在 central widget 上
|
||||||
@@ -733,6 +856,12 @@ class MainWindow(QMainWindow):
|
|||||||
# ─────────────────────────────────
|
# ─────────────────────────────────
|
||||||
|
|
||||||
def _build_ui(self):
|
def _build_ui(self):
|
||||||
|
# 菜单栏
|
||||||
|
settings_menu = self.menuBar().addMenu("设置")
|
||||||
|
action_pref = QAction("程序设置…", self)
|
||||||
|
action_pref.triggered.connect(self._show_settings)
|
||||||
|
settings_menu.addAction(action_pref)
|
||||||
|
|
||||||
central = QWidget()
|
central = QWidget()
|
||||||
self.setCentralWidget(central)
|
self.setCentralWidget(central)
|
||||||
root = QVBoxLayout(central)
|
root = QVBoxLayout(central)
|
||||||
@@ -742,13 +871,13 @@ class MainWindow(QMainWindow):
|
|||||||
# 版权信息栏(右上角)
|
# 版权信息栏(右上角)
|
||||||
if _COPYRIGHT:
|
if _COPYRIGHT:
|
||||||
cr_bar = QWidget()
|
cr_bar = QWidget()
|
||||||
cr_bar.setFixedHeight(22)
|
cr_bar.setFixedHeight(_sz(22))
|
||||||
cr_bar.setStyleSheet("background: #222;")
|
cr_bar.setStyleSheet("background: #222;")
|
||||||
cr_layout = QHBoxLayout(cr_bar)
|
cr_layout = QHBoxLayout(cr_bar)
|
||||||
cr_layout.setContentsMargins(8, 0, 10, 0)
|
cr_layout.setContentsMargins(8, 0, 10, 0)
|
||||||
cr_layout.addStretch()
|
cr_layout.addStretch()
|
||||||
cr_lbl = QLabel(f"© {_COPYRIGHT}")
|
cr_lbl = QLabel(f"© {_COPYRIGHT}")
|
||||||
cr_lbl.setStyleSheet("color: #888; font-size: 11px;")
|
cr_lbl.setStyleSheet(f"color: #888; font-size:{_fs(11)}px;")
|
||||||
cr_layout.addWidget(cr_lbl)
|
cr_layout.addWidget(cr_lbl)
|
||||||
root.addWidget(cr_bar)
|
root.addWidget(cr_bar)
|
||||||
|
|
||||||
@@ -757,13 +886,17 @@ class MainWindow(QMainWindow):
|
|||||||
tabs.addTab(self._build_d2c_tab(), " Orbbec Viewer 深度图 D2C ")
|
tabs.addTab(self._build_d2c_tab(), " Orbbec Viewer 深度图 D2C ")
|
||||||
root.addWidget(tabs)
|
root.addWidget(tabs)
|
||||||
|
|
||||||
|
def _show_settings(self):
|
||||||
|
dlg = SettingsDialog(self._app_settings, self)
|
||||||
|
dlg.exec_()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _step_group(num: int, title: str) -> QGroupBox:
|
def _step_group(num: int, title: str) -> QGroupBox:
|
||||||
grp = QGroupBox(f"第 {num} 步 · {title}")
|
grp = QGroupBox(f"第 {num} 步 · {title}")
|
||||||
grp.setStyleSheet(
|
grp.setStyleSheet(
|
||||||
"QGroupBox { font-weight:bold; font-size:12px; color:#8ec8ff;"
|
f"QGroupBox {{ font-weight:bold; font-size:{_fs(12)}px; color:#8ec8ff;"
|
||||||
" border:1px solid #444; border-radius:5px; margin-top:6px; padding-top:4px; }"
|
f" border:1px solid #444; border-radius:5px; margin-top:6px; padding-top:4px; }}"
|
||||||
"QGroupBox::title { subcontrol-origin:margin; left:10px; padding:0 4px; }"
|
f"QGroupBox::title {{ subcontrol-origin:margin; left:10px; padding:0 4px; }}"
|
||||||
)
|
)
|
||||||
return grp
|
return grp
|
||||||
|
|
||||||
@@ -780,11 +913,11 @@ class MainWindow(QMainWindow):
|
|||||||
g1 = QHBoxLayout(grp1)
|
g1 = QHBoxLayout(grp1)
|
||||||
g1.setContentsMargins(8, 4, 8, 6)
|
g1.setContentsMargins(8, 4, 8, 6)
|
||||||
refresh_btn = QPushButton("刷新设备")
|
refresh_btn = QPushButton("刷新设备")
|
||||||
refresh_btn.setFixedHeight(28)
|
refresh_btn.setFixedHeight(_sz(28))
|
||||||
refresh_btn.clicked.connect(self._refresh_devices)
|
refresh_btn.clicked.connect(self._refresh_devices)
|
||||||
g1.addWidget(refresh_btn)
|
g1.addWidget(refresh_btn)
|
||||||
self.device_status = QLabel("未连接设备,请点击「刷新设备」")
|
self.device_status = QLabel("未连接设备,请点击「刷新设备」")
|
||||||
self.device_status.setStyleSheet("color:#aaa; font-size:12px;")
|
self.device_status.setStyleSheet(f"color:#aaa; font-size:{_fs(12)}px;")
|
||||||
g1.addWidget(self.device_status)
|
g1.addWidget(self.device_status)
|
||||||
g1.addStretch()
|
g1.addStretch()
|
||||||
layout.addWidget(grp1)
|
layout.addWidget(grp1)
|
||||||
@@ -797,23 +930,26 @@ class MainWindow(QMainWindow):
|
|||||||
|
|
||||||
g2.addWidget(QLabel("RGB:"))
|
g2.addWidget(QLabel("RGB:"))
|
||||||
self.color_combo = QComboBox()
|
self.color_combo = QComboBox()
|
||||||
self.color_combo.setMinimumWidth(250)
|
self.color_combo.setMinimumWidth(_sz(280))
|
||||||
self.color_combo.setMaxVisibleItems(12)
|
self.color_combo.setSizeAdjustPolicy(QComboBox.AdjustToContents)
|
||||||
|
self.color_combo.setMaxVisibleItems(15)
|
||||||
self.color_combo.setStyleSheet(COMBO_CSS)
|
self.color_combo.setStyleSheet(COMBO_CSS)
|
||||||
g2.addWidget(self.color_combo)
|
g2.addWidget(self.color_combo)
|
||||||
|
|
||||||
g2.addSpacing(12)
|
g2.addSpacing(12)
|
||||||
g2.addWidget(QLabel("深度:"))
|
g2.addWidget(QLabel("深度:"))
|
||||||
self.depth_combo = QComboBox()
|
self.depth_combo = QComboBox()
|
||||||
self.depth_combo.setMinimumWidth(250)
|
self.depth_combo.setMinimumWidth(_sz(280))
|
||||||
self.depth_combo.setMaxVisibleItems(12)
|
self.depth_combo.setSizeAdjustPolicy(QComboBox.AdjustToContents)
|
||||||
|
self.depth_combo.setMaxVisibleItems(15)
|
||||||
self.depth_combo.setStyleSheet(COMBO_CSS)
|
self.depth_combo.setStyleSheet(COMBO_CSS)
|
||||||
g2.addWidget(self.depth_combo)
|
g2.addWidget(self.depth_combo)
|
||||||
|
|
||||||
g2.addSpacing(12)
|
g2.addSpacing(12)
|
||||||
g2.addWidget(QLabel("Preset:"))
|
g2.addWidget(QLabel("Preset:"))
|
||||||
self.preset_combo = QComboBox()
|
self.preset_combo = QComboBox()
|
||||||
self.preset_combo.setMinimumWidth(160)
|
self.preset_combo.setMinimumWidth(_sz(180))
|
||||||
|
self.preset_combo.setSizeAdjustPolicy(QComboBox.AdjustToContents)
|
||||||
self.preset_combo.setMaxVisibleItems(12)
|
self.preset_combo.setMaxVisibleItems(12)
|
||||||
self.preset_combo.setStyleSheet(COMBO_CSS)
|
self.preset_combo.setStyleSheet(COMBO_CSS)
|
||||||
self.preset_combo.setEnabled(False)
|
self.preset_combo.setEnabled(False)
|
||||||
@@ -822,7 +958,7 @@ class MainWindow(QMainWindow):
|
|||||||
g2.addStretch()
|
g2.addStretch()
|
||||||
self.stream_btn = QPushButton("开启")
|
self.stream_btn = QPushButton("开启")
|
||||||
self.stream_btn.setCheckable(True)
|
self.stream_btn.setCheckable(True)
|
||||||
self.stream_btn.setFixedSize(88, 30)
|
self.stream_btn.setFixedSize(_sz(88), _sz(30))
|
||||||
self.stream_btn.setStyleSheet(
|
self.stream_btn.setStyleSheet(
|
||||||
"QPushButton{ border-radius:5px; border:none; font-weight:bold; }"
|
"QPushButton{ border-radius:5px; border:none; font-weight:bold; }"
|
||||||
"QPushButton:!checked{ background:#555; color:#ccc; }"
|
"QPushButton:!checked{ background:#555; color:#ccc; }"
|
||||||
@@ -841,16 +977,16 @@ class MainWindow(QMainWindow):
|
|||||||
|
|
||||||
today = datetime.now()
|
today = datetime.now()
|
||||||
self.session_edit = QLineEdit(f"{today.year}年{today.month}月{today.day}日")
|
self.session_edit = QLineEdit(f"{today.year}年{today.month}月{today.day}日")
|
||||||
self.session_edit.setMinimumWidth(160)
|
self.session_edit.setMinimumWidth(_sz(160))
|
||||||
g3.addWidget(self.session_edit)
|
g3.addWidget(self.session_edit)
|
||||||
|
|
||||||
create_btn = QPushButton("创建 / 载入")
|
create_btn = QPushButton("创建 / 载入")
|
||||||
create_btn.setFixedHeight(28)
|
create_btn.setFixedHeight(_sz(28))
|
||||||
create_btn.clicked.connect(self._create_session)
|
create_btn.clicked.connect(self._create_session)
|
||||||
g3.addWidget(create_btn)
|
g3.addWidget(create_btn)
|
||||||
|
|
||||||
self.session_status = QLabel("(未创建)")
|
self.session_status = QLabel("(未创建)")
|
||||||
self.session_status.setStyleSheet("color:gray; font-size:12px;")
|
self.session_status.setStyleSheet(f"color:gray; font-size:{_fs(12)}px;")
|
||||||
g3.addWidget(self.session_status)
|
g3.addWidget(self.session_status)
|
||||||
g3.addStretch()
|
g3.addStretch()
|
||||||
|
|
||||||
@@ -873,11 +1009,11 @@ class MainWindow(QMainWindow):
|
|||||||
box = QVBoxLayout()
|
box = QVBoxLayout()
|
||||||
hdr = QLabel(title)
|
hdr = QLabel(title)
|
||||||
hdr.setAlignment(Qt.AlignCenter)
|
hdr.setAlignment(Qt.AlignCenter)
|
||||||
hdr.setStyleSheet("font-weight:bold; font-size:13px;")
|
hdr.setStyleSheet(f"font-weight:bold; font-size:{_fs(13)}px;")
|
||||||
box.addWidget(hdr)
|
box.addWidget(hdr)
|
||||||
lbl = QLabel("等待画面…")
|
lbl = QLabel("等待画面…")
|
||||||
lbl.setAlignment(Qt.AlignCenter)
|
lbl.setAlignment(Qt.AlignCenter)
|
||||||
lbl.setMinimumSize(540, 360)
|
lbl.setMinimumSize(_sz(540), _sz(360))
|
||||||
lbl.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
|
lbl.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
|
||||||
lbl.setStyleSheet("background:#111; border:1px solid #555; color:#666;")
|
lbl.setStyleSheet("background:#111; border:1px solid #555; color:#666;")
|
||||||
setattr(self, attr, lbl)
|
setattr(self, attr, lbl)
|
||||||
@@ -890,18 +1026,18 @@ class MainWindow(QMainWindow):
|
|||||||
step4_row = QHBoxLayout()
|
step4_row = QHBoxLayout()
|
||||||
step4_lbl = QLabel("第 4 步 · 拍照")
|
step4_lbl = QLabel("第 4 步 · 拍照")
|
||||||
step4_lbl.setStyleSheet(
|
step4_lbl.setStyleSheet(
|
||||||
"color:#8ec8ff; font-weight:bold; font-size:12px;")
|
f"color:#8ec8ff; font-weight:bold; font-size:{_fs(12)}px;")
|
||||||
step4_row.addWidget(step4_lbl)
|
step4_row.addWidget(step4_lbl)
|
||||||
step4_row.addStretch()
|
step4_row.addStretch()
|
||||||
|
|
||||||
hint = QLabel("快捷键 S")
|
hint = QLabel("快捷键 S")
|
||||||
hint.setStyleSheet("color:#666; font-size:11px;")
|
hint.setStyleSheet(f"color:#666; font-size:{_fs(11)}px;")
|
||||||
step4_row.addWidget(hint)
|
step4_row.addWidget(hint)
|
||||||
|
|
||||||
self.capture_btn = QPushButton("拍照")
|
self.capture_btn = QPushButton("拍照")
|
||||||
self.capture_btn.setFixedSize(160, 44)
|
self.capture_btn.setFixedSize(_sz(160), _sz(44))
|
||||||
self.capture_btn.setEnabled(False)
|
self.capture_btn.setEnabled(False)
|
||||||
f = QFont(); f.setPointSize(13); f.setBold(True)
|
f = QFont(); f.setPointSize(_fs(13)); f.setBold(True)
|
||||||
self.capture_btn.setFont(f)
|
self.capture_btn.setFont(f)
|
||||||
self.capture_btn.setStyleSheet(
|
self.capture_btn.setStyleSheet(
|
||||||
"QPushButton{ background:#2a6ebb; color:white; border-radius:8px; border:none; }"
|
"QPushButton{ background:#2a6ebb; color:white; border-radius:8px; border:none; }"
|
||||||
@@ -928,11 +1064,11 @@ class MainWindow(QMainWindow):
|
|||||||
g1 = QHBoxLayout(grp1)
|
g1 = QHBoxLayout(grp1)
|
||||||
g1.setContentsMargins(8, 4, 8, 6)
|
g1.setContentsMargins(8, 4, 8, 6)
|
||||||
d2c_refresh_btn = QPushButton("刷新设备")
|
d2c_refresh_btn = QPushButton("刷新设备")
|
||||||
d2c_refresh_btn.setFixedHeight(28)
|
d2c_refresh_btn.setFixedHeight(_sz(28))
|
||||||
d2c_refresh_btn.clicked.connect(self._refresh_devices)
|
d2c_refresh_btn.clicked.connect(self._refresh_devices)
|
||||||
g1.addWidget(d2c_refresh_btn)
|
g1.addWidget(d2c_refresh_btn)
|
||||||
self.d2c_device_status = QLabel("未连接设备,请点击「刷新设备」")
|
self.d2c_device_status = QLabel("未连接设备,请点击「刷新设备」")
|
||||||
self.d2c_device_status.setStyleSheet("color:#aaa; font-size:12px;")
|
self.d2c_device_status.setStyleSheet(f"color:#aaa; font-size:{_fs(12)}px;")
|
||||||
g1.addWidget(self.d2c_device_status)
|
g1.addWidget(self.d2c_device_status)
|
||||||
g1.addStretch()
|
g1.addStretch()
|
||||||
layout.addWidget(grp1)
|
layout.addWidget(grp1)
|
||||||
@@ -946,22 +1082,24 @@ class MainWindow(QMainWindow):
|
|||||||
combo_row = QHBoxLayout()
|
combo_row = QHBoxLayout()
|
||||||
combo_row.addWidget(QLabel("RGB:"))
|
combo_row.addWidget(QLabel("RGB:"))
|
||||||
self.d2c_color_combo = QComboBox()
|
self.d2c_color_combo = QComboBox()
|
||||||
self.d2c_color_combo.setMinimumWidth(240)
|
self.d2c_color_combo.setMinimumWidth(_sz(280))
|
||||||
self.d2c_color_combo.setMaxVisibleItems(12)
|
self.d2c_color_combo.setSizeAdjustPolicy(QComboBox.AdjustToContents)
|
||||||
|
self.d2c_color_combo.setMaxVisibleItems(15)
|
||||||
self.d2c_color_combo.setStyleSheet(COMBO_CSS)
|
self.d2c_color_combo.setStyleSheet(COMBO_CSS)
|
||||||
combo_row.addWidget(self.d2c_color_combo)
|
combo_row.addWidget(self.d2c_color_combo)
|
||||||
|
|
||||||
combo_row.addSpacing(12)
|
combo_row.addSpacing(12)
|
||||||
combo_row.addWidget(QLabel("深度:"))
|
combo_row.addWidget(QLabel("深度:"))
|
||||||
self.d2c_depth_combo = QComboBox()
|
self.d2c_depth_combo = QComboBox()
|
||||||
self.d2c_depth_combo.setMinimumWidth(240)
|
self.d2c_depth_combo.setMinimumWidth(_sz(280))
|
||||||
self.d2c_depth_combo.setMaxVisibleItems(12)
|
self.d2c_depth_combo.setSizeAdjustPolicy(QComboBox.AdjustToContents)
|
||||||
|
self.d2c_depth_combo.setMaxVisibleItems(15)
|
||||||
self.d2c_depth_combo.setStyleSheet(COMBO_CSS)
|
self.d2c_depth_combo.setStyleSheet(COMBO_CSS)
|
||||||
combo_row.addWidget(self.d2c_depth_combo)
|
combo_row.addWidget(self.d2c_depth_combo)
|
||||||
|
|
||||||
combo_row.addSpacing(12)
|
combo_row.addSpacing(12)
|
||||||
fetch_btn = QPushButton("从设备获取参数")
|
fetch_btn = QPushButton("从设备获取参数")
|
||||||
fetch_btn.setFixedHeight(28)
|
fetch_btn.setFixedHeight(_sz(28))
|
||||||
fetch_btn.clicked.connect(self._fetch_params_from_device)
|
fetch_btn.clicked.connect(self._fetch_params_from_device)
|
||||||
combo_row.addWidget(fetch_btn)
|
combo_row.addWidget(fetch_btn)
|
||||||
combo_row.addStretch()
|
combo_row.addStretch()
|
||||||
@@ -969,20 +1107,20 @@ class MainWindow(QMainWindow):
|
|||||||
|
|
||||||
sep = QLabel("── 或直接指定 JSON 文件 ──")
|
sep = QLabel("── 或直接指定 JSON 文件 ──")
|
||||||
sep.setAlignment(Qt.AlignCenter)
|
sep.setAlignment(Qt.AlignCenter)
|
||||||
sep.setStyleSheet("color:#666; font-size:11px;")
|
sep.setStyleSheet(f"color:#666; font-size:{_fs(11)}px;")
|
||||||
pg.addWidget(sep)
|
pg.addWidget(sep)
|
||||||
|
|
||||||
json_row = QHBoxLayout()
|
json_row = QHBoxLayout()
|
||||||
self.params_path_edit = QLineEdit()
|
self.params_path_edit = QLineEdit()
|
||||||
self.params_path_edit.setPlaceholderText("留空则使用上方自动查找结果…")
|
self.params_path_edit.setPlaceholderText("留空则使用上方自动查找结果…")
|
||||||
json_row.addWidget(self.params_path_edit)
|
json_row.addWidget(self.params_path_edit)
|
||||||
br2 = QPushButton("浏览…"); br2.setFixedWidth(70)
|
br2 = QPushButton("浏览…"); br2.setFixedWidth(_sz(70))
|
||||||
br2.clicked.connect(lambda: self._browse_json(self.params_path_edit))
|
br2.clicked.connect(lambda: self._browse_json(self.params_path_edit))
|
||||||
json_row.addWidget(br2)
|
json_row.addWidget(br2)
|
||||||
pg.addLayout(json_row)
|
pg.addLayout(json_row)
|
||||||
|
|
||||||
self.params_selected_lbl = QLabel("(尚未选定参数文件)")
|
self.params_selected_lbl = QLabel("(尚未选定参数文件)")
|
||||||
self.params_selected_lbl.setStyleSheet("color:#888; font-size:12px;")
|
self.params_selected_lbl.setStyleSheet(f"color:#888; font-size:{_fs(12)}px;")
|
||||||
pg.addWidget(self.params_selected_lbl)
|
pg.addWidget(self.params_selected_lbl)
|
||||||
layout.addWidget(grp2)
|
layout.addWidget(grp2)
|
||||||
|
|
||||||
@@ -994,7 +1132,7 @@ class MainWindow(QMainWindow):
|
|||||||
self.d2c_dir_edit = QLineEdit()
|
self.d2c_dir_edit = QLineEdit()
|
||||||
self.d2c_dir_edit.setPlaceholderText("选择包含 PNG 深度图的文件夹…")
|
self.d2c_dir_edit.setPlaceholderText("选择包含 PNG 深度图的文件夹…")
|
||||||
g3.addWidget(self.d2c_dir_edit)
|
g3.addWidget(self.d2c_dir_edit)
|
||||||
br1 = QPushButton("浏览…"); br1.setFixedWidth(70)
|
br1 = QPushButton("浏览…"); br1.setFixedWidth(_sz(70))
|
||||||
br1.clicked.connect(lambda: self._browse_dir(self.d2c_dir_edit))
|
br1.clicked.connect(lambda: self._browse_dir(self.d2c_dir_edit))
|
||||||
g3.addWidget(br1)
|
g3.addWidget(br1)
|
||||||
layout.addWidget(grp3)
|
layout.addWidget(grp3)
|
||||||
@@ -1002,14 +1140,14 @@ class MainWindow(QMainWindow):
|
|||||||
# ── 第 4 步:开始转换 ──
|
# ── 第 4 步:开始转换 ──
|
||||||
step4_row = QHBoxLayout()
|
step4_row = QHBoxLayout()
|
||||||
step4_lbl = QLabel("第 4 步 · 开始转换")
|
step4_lbl = QLabel("第 4 步 · 开始转换")
|
||||||
step4_lbl.setStyleSheet("color:#8ec8ff; font-weight:bold; font-size:12px;")
|
step4_lbl.setStyleSheet(f"color:#8ec8ff; font-weight:bold; font-size:{_fs(12)}px;")
|
||||||
step4_row.addWidget(step4_lbl)
|
step4_row.addWidget(step4_lbl)
|
||||||
self.splat_check = QCheckBox("Splat 3×3 填充(减少 D2C 空洞,默认开启)")
|
self.splat_check = QCheckBox("Splat 3×3 填充(减少 D2C 空洞,默认开启)")
|
||||||
self.splat_check.setChecked(True)
|
self.splat_check.setChecked(True)
|
||||||
step4_row.addWidget(self.splat_check)
|
step4_row.addWidget(self.splat_check)
|
||||||
step4_row.addStretch()
|
step4_row.addStretch()
|
||||||
self.run_d2c_btn = QPushButton("▶ 开始批量 D2C 转换")
|
self.run_d2c_btn = QPushButton("▶ 开始批量 D2C 转换")
|
||||||
self.run_d2c_btn.setFixedHeight(36)
|
self.run_d2c_btn.setFixedHeight(_sz(36))
|
||||||
self.run_d2c_btn.setStyleSheet(
|
self.run_d2c_btn.setStyleSheet(
|
||||||
"QPushButton{ background:#2a7a2a; color:white; border-radius:6px; border:none; }"
|
"QPushButton{ background:#2a7a2a; color:white; border-radius:6px; border:none; }"
|
||||||
"QPushButton:hover{ background:#3a9a3a; }"
|
"QPushButton:hover{ background:#3a9a3a; }"
|
||||||
@@ -1024,7 +1162,7 @@ class MainWindow(QMainWindow):
|
|||||||
self.d2c_log = QTextEdit()
|
self.d2c_log = QTextEdit()
|
||||||
self.d2c_log.setReadOnly(True)
|
self.d2c_log.setReadOnly(True)
|
||||||
self.d2c_log.setStyleSheet(
|
self.d2c_log.setStyleSheet(
|
||||||
"font-family: Consolas,'Courier New',monospace; font-size:12px;")
|
f"font-family: Consolas,'Courier New',monospace; font-size:{_fs(12)}px;")
|
||||||
layout.addWidget(self.d2c_log, stretch=1)
|
layout.addWidget(self.d2c_log, stretch=1)
|
||||||
|
|
||||||
return w
|
return w
|
||||||
@@ -1404,6 +1542,14 @@ def main():
|
|||||||
app = QApplication(sys.argv)
|
app = QApplication(sys.argv)
|
||||||
app.setStyle("Fusion")
|
app.setStyle("Fusion")
|
||||||
|
|
||||||
|
global _UI_SCALE
|
||||||
|
_cfg = AppSettings()
|
||||||
|
_UI_SCALE = _cfg.get_scale_factor()
|
||||||
|
if _UI_SCALE != 1.0:
|
||||||
|
base = app.font()
|
||||||
|
base.setPointSizeF(base.pointSizeF() * _UI_SCALE)
|
||||||
|
app.setFont(base)
|
||||||
|
|
||||||
from PyQt5.QtGui import QPalette, QColor
|
from PyQt5.QtGui import QPalette, QColor
|
||||||
pal = QPalette()
|
pal = QPalette()
|
||||||
pal.setColor(QPalette.Window, QColor(45, 45, 45))
|
pal.setColor(QPalette.Window, QColor(45, 45, 45))
|
||||||
|
|||||||
Reference in New Issue
Block a user