[patch] 优化版本管理显示 与 更新提示(修改表名信息) 修复因线程安全问题导致的崩溃

This commit is contained in:
2025-10-10 12:04:17 +08:00
parent c819bdaa1c
commit 42633da853
2 changed files with 70 additions and 11 deletions

View File

@@ -245,11 +245,18 @@ class WebSocketManager:
self._log(f"❌ 启动版本检查器失败: {e}", "ERROR") self._log(f"❌ 启动版本检查器失败: {e}", "ERROR")
def _on_update_available(self, latest_version, download_url): def _on_update_available(self, latest_version, download_url):
"""发现新版本时的处理""" """发现新版本时的处理(在子线程中调用)"""
self._log(f"🔔 发现新版本 {latest_version}", "INFO") self._log(f"🔔 发现新版本 {latest_version}", "INFO")
# 通知主GUI显示更新提醒 # 通知主GUI显示更新提醒(通过 Qt 信号机制,线程安全)
if hasattr(self, 'gui_update_callback') and self.gui_update_callback: if hasattr(self, 'gui_update_callback') and self.gui_update_callback:
self.gui_update_callback(latest_version, download_url) try:
# 直接调用回调(回调内部使用信号机制调度到主线程)
self.gui_update_callback(latest_version, download_url)
self._log(f"✅ 已调用更新回调", "DEBUG")
except Exception as e:
self._log(f"❌ 调用更新回调失败: {e}", "ERROR")
import traceback
self._log(f"详细错误: {traceback.format_exc()}", "ERROR")
def _start_jd_listener(self, store_id: str, cookies: str): def _start_jd_listener(self, store_id: str, cookies: str):
"""启动京东平台监听""" """启动京东平台监听"""

68
main.py
View File

@@ -1,5 +1,5 @@
import sys import sys
from PyQt5.QtCore import Qt from PyQt5.QtCore import Qt, pyqtSignal, QObject
from PyQt5.QtGui import QFont, QPalette, QColor from PyQt5.QtGui import QFont, QPalette, QColor
from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout,
QHBoxLayout, QLabel, QPushButton, QLineEdit, QHBoxLayout, QLabel, QPushButton, QLineEdit,
@@ -19,8 +19,13 @@ setup_file_logging() # 生产环境启用自动日志功能
print("文件日志系统已在main.py中初始化") print("文件日志系统已在main.py中初始化")
# 新增: 用户名密码输入对话框类 # 新增: 版本更新信号类(用于线程安全的 GUI 通知)
class UpdateSignals(QObject):
"""版本更新信号"""
update_available = pyqtSignal(str, str) # (latest_version, download_url)
# 新增: 用户名密码输入对话框类
class LoginWindow(QMainWindow): class LoginWindow(QMainWindow):
def __init__(self): def __init__(self):
super().__init__() super().__init__()
@@ -41,6 +46,10 @@ class LoginWindow(QMainWindow):
# 日志管理相关变量已删除 # 日志管理相关变量已删除
# 创建版本更新信号对象(线程安全)
self.update_signals = UpdateSignals()
self.update_signals.update_available.connect(self._show_update_dialog)
self.initUI() self.initUI()
# 延迟设置版本检查器确保WebSocket连接已建立 # 延迟设置版本检查器确保WebSocket连接已建立
@@ -708,12 +717,35 @@ class LoginWindow(QMainWindow):
from WebSocket.backend_singleton import get_websocket_manager from WebSocket.backend_singleton import get_websocket_manager
ws_manager = get_websocket_manager() ws_manager = get_websocket_manager()
if ws_manager: if ws_manager:
ws_manager.gui_update_callback = self.show_update_notification # 设置回调为信号发射函数(线程安全)
ws_manager.gui_update_callback = self.emit_update_signal
self.add_log("✅ 版本检查器GUI回调已设置", "SUCCESS") self.add_log("✅ 版本检查器GUI回调已设置", "SUCCESS")
else: else:
self.add_log("⚠️ WebSocket管理器未初始化", "WARNING") self.add_log("⚠️ WebSocket管理器未初始化", "WARNING")
except Exception as e: except Exception as e:
self.add_log(f"❌ 设置版本检查器失败: {e}", "ERROR") self.add_log(f"❌ 设置版本检查器失败: {e}", "ERROR")
def emit_update_signal(self, latest_version, download_url):
"""发射更新信号(可以在任何线程中调用)"""
try:
self.add_log(f"📡 收到更新通知,准备发射信号: v{latest_version}", "INFO")
# 发射信号Qt 自动调度到主线程)
self.update_signals.update_available.emit(latest_version, download_url)
self.add_log(f"✅ 更新信号已发射", "DEBUG")
except Exception as e:
self.add_log(f"❌ 发射更新信号失败: {e}", "ERROR")
import traceback
self.add_log(f"详细错误: {traceback.format_exc()}", "ERROR")
def _show_update_dialog(self, latest_version, download_url):
"""显示更新对话框(信号槽函数,始终在主线程中执行)"""
try:
self.add_log(f"🎯 主线程收到更新信号: v{latest_version}", "INFO")
self.show_update_notification(latest_version, download_url)
except Exception as e:
self.add_log(f"❌ 显示更新对话框失败: {e}", "ERROR")
import traceback
self.add_log(f"详细错误: {traceback.format_exc()}", "ERROR")
def show_update_notification(self, latest_version, download_url): def show_update_notification(self, latest_version, download_url):
"""显示版本更新通知""" """显示版本更新通知"""
@@ -757,7 +789,6 @@ class LoginWindow(QMainWindow):
def trigger_update(self, download_url, latest_version): def trigger_update(self, download_url, latest_version):
"""触发更新下载""" """触发更新下载"""
import webbrowser
try: try:
# 检查下载地址是否有效 # 检查下载地址是否有效
if not download_url or download_url.strip() == "": if not download_url or download_url.strip() == "":
@@ -770,11 +801,32 @@ class LoginWindow(QMainWindow):
) )
return return
self.add_log(f"📂 打开下载页面: {download_url}", "INFO") self.add_log(f"📂 准备打开下载页面: {download_url}", "INFO")
webbrowser.open(download_url)
self.add_log("✅ 已打开更新下载页面", "SUCCESS") # 使用线程安全的方式打开浏览器
try:
import webbrowser
import threading
def open_browser():
"""在独立线程中打开浏览器,避免阻塞主线程"""
try:
webbrowser.open(download_url)
self.add_log("✅ 浏览器已打开", "SUCCESS")
except Exception as e:
self.add_log(f"❌ 打开浏览器失败: {e}", "ERROR")
# 在新线程中打开浏览器
browser_thread = threading.Thread(target=open_browser, daemon=True)
browser_thread.start()
self.add_log(f"✅ 已启动浏览器线程", "INFO")
except Exception as browser_error:
self.add_log(f"❌ 浏览器线程启动失败: {browser_error}", "ERROR")
except Exception as e: except Exception as e:
self.add_log(f"打开下载页面失败: {e}", "ERROR") self.add_log(f"触发更新失败: {e}", "ERROR")
import traceback import traceback
self.add_log(f"详细错误: {traceback.format_exc()}", "ERROR") self.add_log(f"详细错误: {traceback.format_exc()}", "ERROR")