Compare commits

...

3 Commits

Author SHA1 Message Date
marcinlei@outlook.com
c6d3d57358 fix: 无日志上传时显示提示框 2025-08-24 22:49:38 +08:00
marcinlei@outlook.com
f58eda0421 feat(添加favicon) 2025-08-24 22:37:27 +08:00
marcinlei@outlook.com
5169a6c759 perf(timelineEvent) 优化事件时间线中固件更新事件点的描述 2025-08-24 17:38:36 +08:00
16 changed files with 144 additions and 56 deletions

@ -1,47 +1,66 @@
# -*- mode: python ; coding: utf-8 -*- # -*- mode: python ; coding: utf-8 -*-
import os
block_cipher = None import sys
from PyInstaller.utils.hooks import collect_data_files
# 定义所有需要打包的文件和依赖
a = Analysis( block_cipher = None
['./src/main.py'], # 程序入口文件 # 获取spec文件所在目录项目根目录
pathex=['./'], # 工程根目录(确保能找到子模块) spec_dir = os.path.dirname(os.path.abspath(sys.argv[0]))
binaries=[],
# 配置资源文件(子模块会自动识别,主要配置非.py文件 # 定义需要打包的资源文件
datas=[ resource_files = [
# 若有其他资源(如.ui文件、图片等按此格式添加 # 将resource文件夹下的所有文件打包到程序内的resource目录
], (os.path.join(spec_dir, 'resource'), 'resource')
# 隐藏依赖(若打包后提示缺少模块,添加在这里) ]
hiddenimports=[
], # 收集PyQt相关的数据文件
hookspath=[], qt_data = collect_data_files('PyQt5')
hooksconfig={},
runtime_hooks=[], # 合并所有资源文件
excludes=[], # 排除不需要的模块(减小体积) all_resources = resource_files + qt_data
noarchive=False,
cipher=block_cipher, # 定义所有需要打包的文件和依赖
) a = Analysis(
['./src/main.py'], # 程序入口文件
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher) pathex=['./'], # 工程根目录(确保能找到子模块)
binaries=[],
exe = EXE( # 配置资源文件(子模块会自动识别,主要配置非.py文件
pyz, datas=[
a.scripts, # 若有其他资源(如.ui文件、图片等按此格式添加
a.binaries, ],
a.zipfiles, # 隐藏依赖(若打包后提示缺少模块,添加在这里)
a.datas, hiddenimports=[
name='OneKeyDiag', # 生成的EXE文件名 ],
debug=False, hookspath=[],
bootloader_ignore_signals=False, hooksconfig={},
strip=False, runtime_hooks=[],
upx=True, # 启用压缩(推荐) excludes=[], # 排除不需要的模块(减小体积)
upx_exclude=[], noarchive=False,
runtime_tmpdir=None, cipher=block_cipher,
console=False, # 隐藏控制台GUI程序 )
disable_windowed_traceback=False,
argv_emulation=False, pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
target_arch=None,
codesign_identity=None, exe = EXE(
entitlements_file=None, pyz,
) a.scripts,
a.binaries,
a.zipfiles,
a.datas,
name='OneKeyDiag', # 生成的EXE文件名
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True, # 启用压缩(推荐)
upx_exclude=[],
runtime_tmpdir=None,
console=False, # 隐藏控制台GUI程序
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
# 指定程序图标使用resources文件夹中的ico文件
icon=os.path.join(spec_dir, 'resource','favicon.ico'),
)

BIN
resource/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 451 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 965 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

@ -0,0 +1,19 @@
{
"name": "",
"short_name": "",
"icons": [
{
"src": "/android-chrome-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "/android-chrome-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
],
"theme_color": "#ffffff",
"background_color": "#ffffff",
"display": "standalone"
}

@ -138,7 +138,7 @@ def parse_common_event_to_json(log_str, keys):
case "S0/G0": case "S0/G0":
title = "电源状态Up" title = "电源状态Up"
case "FW UPDATE": case "FW UPDATE":
title = "固件更新" title = f"{idl_dict['sensor']}固件更新"
cause = idl_dict['description'] cause = idl_dict['description']
details_info['版本变更'] = cause details_info['版本变更'] = cause
case _: case _:

@ -36,7 +36,10 @@ class EventHandler:
# 获取选中项对应的路径关键词 # 获取选中项对应的路径关键词
key = self.main_window.combo_box_text_dict.get(selected_text) key = self.main_window.combo_box_text_dict.get(selected_text)
if key: if key:
self.view_renderer.display_pic(self.main_window.file_processor.get_sensorhistory_path(key)) self.view_renderer.display_pic(
self.main_window.file_processor.get_sensorhistory_path(key),
self.main_window.parse_status.diag_complete_status
)
def dragEnterEvent(self, event: QDragEnterEvent): def dragEnterEvent(self, event: QDragEnterEvent):
"""拖入事件:判断是否为文件""" """拖入事件:判断是否为文件"""

@ -61,7 +61,10 @@ class FileProcessor:
# 更新传感器图片 # 更新传感器图片
if self.parse_status.sensorhistory_status: if self.parse_status.sensorhistory_status:
self.view_renderer.display_pic(self.get_sensorhistory_path("all")) self.view_renderer.display_pic(
self.get_sensorhistory_path("all"),
self.parse_status.diag_complete_status
)
# 更新告警表格 # 更新告警表格
if self.parse_status.parseidl_status and not service.is_idl_alert_empty(): if self.parse_status.parseidl_status and not service.is_idl_alert_empty():

@ -1,13 +1,30 @@
import os
import sys import sys
import service import service
from PyQt5.QtWidgets import QApplication from PyQt5.QtWidgets import QApplication
from PyQt5.QtGui import QIcon
from main_window import MainWindow # 导入重构后的主窗口类 from main_window import MainWindow # 导入重构后的主窗口类
if __name__ == "__main__": if __name__ == "__main__":
# Windows系统特定设置确保任务栏图标正确显示
try:
from ctypes import windll
myappid = 'marcin.ZiJin.onekeydiag.1.0' # 自定义唯一ID
windll.shell32.SetCurrentProcessExplicitAppUserModelID(myappid)
except ImportError:
pass # 非Windows系统忽略
# 初始化服务缓存 # 初始化服务缓存
service.app_cache_init() service.app_cache_init()
# 创建PyQt应用实例 # 创建PyQt应用实例
app = QApplication(sys.argv) app = QApplication(sys.argv)
# 获取文件系统中存放的icon
icon_path = service.get_icon_path()
if os.path.exists(icon_path):
app.setWindowIcon(QIcon(icon_path))
else:
print("not found favicon")
# 初始化并显示主窗口 # 初始化并显示主窗口
window = MainWindow() window = MainWindow()
window.show() window.show()

@ -8,6 +8,7 @@ import ZiJin_parse_event as zijin_event
class ServiceStatus(): class ServiceStatus():
def __init__(self): def __init__(self):
self.diag_complete_status = False
self.sensorhistory_status = False self.sensorhistory_status = False
self.baseinfo_status = False self.baseinfo_status = False
self.parseidl_status = False self.parseidl_status = False
@ -43,7 +44,17 @@ def app_cache_init():
utils.clean_log_data(cache_dir) utils.clean_log_data(cache_dir)
os.mkdir(cache_dir) os.mkdir(cache_dir)
pass
def get_icon_path():
"""获取资源文件的绝对路径"""
try:
# 打包后的环境
base_path = sys._MEIPASS
except AttributeError:
# 开发环境:
base_path = utils.get_project_root()
resource_dir = os.path.join(base_path, "resource")
return os.path.join(resource_dir, "favicon.ico")
def send_log_to_cache(filepath): def send_log_to_cache(filepath):
project_root = utils.get_project_root() project_root = utils.get_project_root()
@ -76,4 +87,7 @@ def start_diagnose(parseStatus):
parseStatus.set_parseidl_status(result_parseidl) parseStatus.set_parseidl_status(result_parseidl)
result_eventline = zijin_event.program_main() result_eventline = zijin_event.program_main()
parseStatus.set_eventline_status(result_eventline) parseStatus.set_eventline_status(result_eventline)
# 完成文件解析后将 diag_complete_status 置位
parseStatus.diag_complete_status = True

@ -5,7 +5,8 @@ from PyQt5.QtWidgets import (QApplication, QWidget, QGraphicsView, QGraphicsScen
QGraphicsTextItem, QToolTip, QVBoxLayout, QGraphicsTextItem, QToolTip, QVBoxLayout,
QTabWidget, QLabel) QTabWidget, QLabel)
from PyQt5.QtCore import Qt, QEvent, QTimer, QPoint from PyQt5.QtCore import Qt, QEvent, QTimer, QPoint
from PyQt5.QtGui import QPen, QBrush, QColor, QFont, QPainter from PyQt5.QtGui import QPen, QBrush, QColor, QFont, QPainter, QIcon
import service
class TimelineEvent: class TimelineEvent:
"""事件数据封装类""" """事件数据封装类"""
@ -230,7 +231,7 @@ class TimelineGraphicsView(QGraphicsView):
return self.group_colors[0] return self.group_colors[0]
case _ if "温度事件" in event.title: case _ if "温度事件" in event.title:
return self.group_colors[1] return self.group_colors[1]
case "固件更新": case _ if "固件更新" in event.title:
return self.group_colors[2] return self.group_colors[2]
case _ if "电压事件" in event.title: case _ if "电压事件" in event.title:
return self.group_colors[3] return self.group_colors[3]
@ -312,6 +313,10 @@ class TimelineTabContent(QWidget):
self.init_ui() self.init_ui()
def init_ui(self): def init_ui(self):
# 设置窗口图标
icon_path = service.get_icon_path()
self.setWindowIcon(QIcon(icon_path))
layout = QVBoxLayout(self) layout = QVBoxLayout(self)
title_label = QLabel("事件时间线") title_label = QLabel("事件时间线")

@ -11,16 +11,24 @@ class ViewRenderer:
# 持有主窗口引用用于访问UI组件如graphicsView、model_alert # 持有主窗口引用用于访问UI组件如graphicsView、model_alert
self.main_window = main_window self.main_window = main_window
def display_pic(self, image_path): def display_pic(self, image_path, completeStatus):
""" """
QGraphicsView 中显示图片支持抗锯齿居中适配 QGraphicsView 中显示图片支持抗锯齿居中适配
:param image_path: 图片文件的绝对路径 :param image_path: 图片文件的绝对路径
""" """
if not completeStatus:
show_info_message(
parent=self.main_window,
title="图片无法显示",
message="当前无日志文件解析\n"
)
return
if not os.path.exists(image_path): if not os.path.exists(image_path):
show_info_message( show_info_message(
parent=self.main_window, parent=self.main_window,
title="图片无法显示", title="图片无法显示",
message="目标日志文件中无温度数据, 可能是BMC版本不支持\n" message="目标日志文件中无温度数据; BMC版本不支持\n"
) )
return return