#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ 工具运行配置: 运行目录定位 / filmforge_gui.json(串口记忆 + 监视设置) ================================================================ PyInstaller onefile 打包后 __file__ 指向临时解压目录, 配置必须落在 exe 旁边, 故 frozen 时改用 sys.executable 定位。 """ import json import os import sys import filmforge_rs485 if getattr(sys, 'frozen', False): BASE_DIR = os.path.dirname(os.path.abspath(sys.executable)) else: BASE_DIR = os.path.dirname(os.path.abspath(__file__)) SETTINGS_FILE = os.path.join(BASE_DIR, 'filmforge_gui.json') LOG_DIR = os.path.join(BASE_DIR, 'logs') # 曲线时间窗候选(秒): 下拉框文案 -> 秒 WINDOW_OPTIONS = (('2 分钟', 120), ('5 分钟', 300), ('15 分钟', 900), ('60 分钟', 3600), ('全部', 0)) DEFAULT_WINDOW_SEC = 300 MAX_SAMPLES = 200000 # 曲线内存上限(点), 超出丢最旧; 10Hz 下约 5.5 小时 # 串口记忆(协议固定 115200-8-N-1, 仍允许改以便调试) SERIAL_CFG = {'port': '', 'baud': filmforge_rs485.DEFAULT_BAUD, 'bytesize': 8, 'parity': 'N', 'stopbits': 1} REPORT_MS = 500 # 上报间隔输入框默认值 WINDOW_SEC = DEFAULT_WINDOW_SEC THEME = 'System' Y_MODE = 'auto' # 曲线 Y 轴(温度轴): 'auto'=自适应 / 'manual'=固定范围 Y_MIN = None # 手动 Y 轴上下限(℃), 仅 Y_MODE='manual' 且合法时生效 Y_MAX = None def load_settings(): """读 filmforge_gui.json(缺失/损坏按默认值), 更新模块级默认字典""" try: with open(SETTINGS_FILE, encoding='utf-8') as f: data = json.load(f) except Exception: return if not isinstance(data, dict): return ser = data.get('serial') if isinstance(ser, dict): SERIAL_CFG['port'] = str(ser.get('port') or '') try: SERIAL_CFG['baud'] = int(ser.get('baud') or filmforge_rs485.DEFAULT_BAUD) except (TypeError, ValueError): pass try: SERIAL_CFG['bytesize'] = int(ser.get('bytesize') or 8) except (TypeError, ValueError): pass SERIAL_CFG['parity'] = str(ser.get('parity') or 'N').upper()[:1] try: SERIAL_CFG['stopbits'] = int(ser.get('stopbits') or 1) except (TypeError, ValueError): pass for key, target in (('report_ms', 'REPORT_MS'), ('window_sec', 'WINDOW_SEC')): try: globals()[target] = int(data.get(key)) except (TypeError, ValueError): pass global THEME theme = str(data.get('theme') or '') if theme in ('Dark', 'Light', 'System'): THEME = theme ax = data.get('y_axis') if isinstance(ax, dict): mode = str(ax.get('mode') or '') if mode in ('auto', 'manual'): globals()['Y_MODE'] = mode try: globals()['Y_MIN'] = round(float(ax.get('min')), 2) except (TypeError, ValueError): pass try: globals()['Y_MAX'] = round(float(ax.get('max')), 2) except (TypeError, ValueError): pass def save_settings(): """写出全部设置(始终写全键)""" data = { 'serial': dict(SERIAL_CFG), 'report_ms': REPORT_MS, 'window_sec': WINDOW_SEC, 'theme': THEME, 'y_axis': {'mode': Y_MODE, 'min': Y_MIN, 'max': Y_MAX}, } try: with open(SETTINGS_FILE, 'w', encoding='utf-8') as f: json.dump(data, f, ensure_ascii=False, indent=2) except OSError: pass # 只读目录(exe 旁)下静默放弃, 不影响运行