[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")
def _on_update_available(self, latest_version, download_url):
"""发现新版本时的处理"""
"""发现新版本时的处理(在子线程中调用)"""
self._log(f"🔔 发现新版本 {latest_version}", "INFO")
# 通知主GUI显示更新提醒
# 通知主GUI显示更新提醒(通过 Qt 信号机制,线程安全)
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):
"""启动京东平台监听"""

68
main.py
View File

@@ -1,5 +1,5 @@
import sys
from PyQt5.QtCore import Qt
from PyQt5.QtCore import Qt, pyqtSignal, QObject
from PyQt5.QtGui import QFont, QPalette, QColor
from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout,
QHBoxLayout, QLabel, QPushButton, QLineEdit,
@@ -19,8 +19,13 @@ setup_file_logging() # 生产环境启用自动日志功能
print("文件日志系统已在main.py中初始化")
# 新增: 用户名密码输入对话框类
# 新增: 版本更新信号类(用于线程安全的 GUI 通知)
class UpdateSignals(QObject):
"""版本更新信号"""
update_available = pyqtSignal(str, str) # (latest_version, download_url)
# 新增: 用户名密码输入对话框类
class LoginWindow(QMainWindow):
def __init__(self):
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()
# 延迟设置版本检查器确保WebSocket连接已建立
@@ -708,12 +717,35 @@ class LoginWindow(QMainWindow):
from WebSocket.backend_singleton import get_websocket_manager
ws_manager = get_websocket_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")
else:
self.add_log("⚠️ WebSocket管理器未初始化", "WARNING")
except Exception as e:
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):
"""显示版本更新通知"""
@@ -757,7 +789,6 @@ class LoginWindow(QMainWindow):
def trigger_update(self, download_url, latest_version):
"""触发更新下载"""
import webbrowser
try:
# 检查下载地址是否有效
if not download_url or download_url.strip() == "":
@@ -770,11 +801,32 @@ class LoginWindow(QMainWindow):
)
return
self.add_log(f"📂 打开下载页面: {download_url}", "INFO")
webbrowser.open(download_url)
self.add_log("✅ 已打开更新下载页面", "SUCCESS")
self.add_log(f"📂 准备打开下载页面: {download_url}", "INFO")
# 使用线程安全的方式打开浏览器
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:
self.add_log(f"打开下载页面失败: {e}", "ERROR")
self.add_log(f"触发更新失败: {e}", "ERROR")
import traceback
self.add_log(f"详细错误: {traceback.format_exc()}", "ERROR")