Files
shuidrop_gui/main.py
haosicheng c58cec750f Todo: 修改因exe_token错误导致的不断重连问题
Todo: 修改打包中.bat打包文件与测试打包脚本不一致问题
New: 新增installer安装包环境搭建数据
2025-09-28 17:00:02 +08:00

755 lines
29 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import sys
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QFont, QPalette, QColor
from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout,
QHBoxLayout, QLabel, QPushButton, QLineEdit,
QTextEdit, QFrame, QDialog, QDialogButtonBox, QComboBox,
QSystemTrayIcon, QMenu, QAction, QMessageBox, QGraphicsDropShadowEffect)
from PyQt5.QtCore import QPropertyAnimation, QEasingCurve, QRect, QTimer, pyqtProperty
from PyQt5.QtGui import QColor
import config
from WebSocket.backend_singleton import get_websocket_manager
from windows_taskbar_fix import setup_windows_taskbar_icon
import os
# ===================== 文件日志系统 - 生产环境启用 =====================
# 重定向所有输出到文件,确保有日志记录
from exe_file_logger import setup_file_logging, log_to_file
setup_file_logging() # 生产环境启用自动日志功能
print("文件日志系统已在main.py中初始化")
# 新增: 用户名密码输入对话框类
class LoginWindow(QMainWindow):
def __init__(self):
super().__init__()
self.jd_worker = None
self.progress_dialog = None
self.douyin_worker = None
self.qian_niu_worker = None
self.pdd_worker = None
# 重复执行防护
self.last_login_time = 0
self.login_cooldown = 2 # 登录冷却时间(秒)
# 平台连接状态管理
self.connected_platforms = []
self.status_timer = None
self.last_platform_connect_time = 0 # 记录最后一次平台连接时间
# 日志管理相关变量已删除
self.initUI()
def initUI(self):
# 设置窗口基本属性
self.setWindowTitle('AI客服智能助手')
self.setGeometry(300, 300, 450, 300) # 进一步减小窗口尺寸
self.setMinimumSize(420, 280) # 设置更小的最小尺寸
self.setMaximumSize(500, 350) # 设置最大尺寸,保持紧凑
# 窗口图标将由统一的任务栏修复模块设置,这里只做备用检查
print("[INFO] 窗口图标将由统一模块设置")
# 创建中央widget
central_widget = QWidget()
self.setCentralWidget(central_widget)
# 创建主布局
main_layout = QVBoxLayout()
main_layout.setSpacing(15) # 减小间距
main_layout.setContentsMargins(30, 20, 30, 20) # 减小边距
central_widget.setLayout(main_layout)
# 添加标题和副标题
title_label = QLabel('AI客服智能助手')
title_label.setObjectName("title")
title_label.setAlignment(Qt.AlignCenter)
title_label.setFont(QFont('Microsoft YaHei', 18, QFont.Bold)) # 减小字体
title_label.setStyleSheet("color: #2c3e50; margin-bottom: 3px;")
main_layout.addWidget(title_label)
# 添加副标题说明
subtitle_label = QLabel('智能连接多平台客服提供AI自动回复服务')
subtitle_label.setObjectName("subtitle")
subtitle_label.setAlignment(Qt.AlignCenter)
subtitle_label.setFont(QFont('Microsoft YaHei', 9)) # 减小字体
subtitle_label.setStyleSheet("color: #7f8c8d; margin-bottom: 10px;")
main_layout.addWidget(subtitle_label)
# 添加少量垂直空间
main_layout.addStretch(1)
# 创建令牌输入区域
token_layout = QVBoxLayout()
token_layout.setSpacing(8) # 减小间距
token_label = QLabel('访问令牌')
token_label.setFont(QFont('Microsoft YaHei', 11, QFont.Bold)) # 减小字体
token_label.setStyleSheet("color: #34495e;")
self.token_input = QLineEdit()
self.token_input.setPlaceholderText('请输入您的访问令牌以连接服务')
self.token_input.setEchoMode(QLineEdit.Password)
self.token_input.setFont(QFont('Microsoft YaHei', 10)) # 减小字体
# noinspection PyUnresolvedReferences
self.token_input.returnPressed.connect(self.login) # 表示回车提交
self.token_input.setMinimumHeight(38) # 减小输入框高度
# 预填已保存的令牌(如果存在)
try:
from config import get_saved_token
saved = get_saved_token()
if saved:
self.token_input.setText(saved)
except Exception:
pass
token_layout.addWidget(token_label)
token_layout.addWidget(self.token_input)
main_layout.addLayout(token_layout)
# 创建连接按钮
self.login_btn = QPushButton('连接服务')
self.login_btn.setFont(QFont('Microsoft YaHei', 11, QFont.Bold)) # 减小字体
self.login_btn.setMinimumHeight(40) # 减小按钮高度
self.login_btn.clicked.connect(self.login) # 表示点击提交
main_layout.addWidget(self.login_btn)
# 添加连接状态提示
self.status_label = QLabel('等待连接...')
self.status_label.setObjectName("status")
self.status_label.setAlignment(Qt.AlignCenter)
self.status_label.setFont(QFont('Microsoft YaHei', 9)) # 减小字体
self.status_label.setStyleSheet("color: #95a5a6; margin-top: 5px;")
main_layout.addWidget(self.status_label)
# 添加少量底部空间
main_layout.addStretch(1)
# 日志框已永久删除,只使用终端输出
self.log_display = None
# 应用现代化样式
self.apply_modern_styles()
# 添加视觉效果
self.add_visual_effects()
# 初始化系统托盘
self.init_system_tray()
# 系统初始化日志输出到终端
print("[INFO] 系统初始化完成")
def apply_modern_styles(self):
"""应用现代化简约样式 - 精致美化版"""
self.setStyleSheet("""
QMainWindow {
background: qlineargradient(
x1:0, y1:0, x2:0, y2:1,
stop:0 #f8fafb,
stop:0.5 #f1f4f6,
stop:1 #e8ecef
);
border: 1px solid rgba(255, 255, 255, 0.3);
}
QLabel {
color: #2c3e50;
background: transparent;
}
QLabel[objectName="title"] {
color: qlineargradient(
x1:0, y1:0, x2:1, y2:0,
stop:0 #2c3e50,
stop:1 #34495e
);
font-weight: bold;
}
QLabel[objectName="subtitle"] {
color: #7f8c8d;
background: transparent;
}
QLabel[objectName="status"] {
padding: 5px 10px;
border-radius: 12px;
background: rgba(149, 165, 166, 0.1);
font-size: 9px;
}
QLineEdit {
padding: 12px 16px;
border: 2px solid transparent;
border-radius: 12px;
font-size: 13px;
background: qlineargradient(
x1:0, y1:0, x2:0, y2:1,
stop:0 #ffffff,
stop:1 #f8fafb
);
selection-background-color: #007bff;
selection-color: white;
color: #2c3e50;
}
QLineEdit:focus {
border: 2px solid #007bff;
background: white;
outline: none;
}
QLineEdit:hover {
border: 2px solid #6c757d;
background: white;
}
QPushButton {
background: qlineargradient(
x1:0, y1:0, x2:0, y2:1,
stop:0 #4285f4,
stop:0.5 #1976d2,
stop:1 #1565c0
);
border: none;
color: white;
padding: 12px 24px;
border-radius: 12px;
font-size: 13px;
font-weight: 600;
min-width: 180px;
letter-spacing: 0.5px;
}
QPushButton:hover {
background: qlineargradient(
x1:0, y1:0, x2:0, y2:1,
stop:0 #5294f5,
stop:0.5 #2986d3,
stop:1 #1e74c1
);
}
QPushButton:pressed {
background: qlineargradient(
x1:0, y1:0, x2:0, y2:1,
stop:0 #3274d4,
stop:0.5 #1666c2,
stop:1 #1455b0
);
}
QPushButton:disabled {
background: qlineargradient(
x1:0, y1:0, x2:0, y2:1,
stop:0 #f8f9fa,
stop:1 #e9ecef
);
color: #6c757d;
border: 1px solid #dee2e6;
}
/* 连接成功状态的按钮 */
QPushButton[objectName="connected"] {
background: qlineargradient(
x1:0, y1:0, x2:0, y2:1,
stop:0 #28a745,
stop:0.5 #20963b,
stop:1 #1e7e34
);
}
QPushButton[objectName="connected"]:hover {
background: qlineargradient(
x1:0, y1:0, x2:0, y2:1,
stop:0 #34ce57,
stop:0.5 #28a745,
stop:1 #20963b
);
}
""")
# 设置全局字体确保各Windows版本显示一致
font = QFont('Microsoft YaHei', 10) # Windows系统自带字体
QApplication.setFont(font)
# 设置调色板确保颜色一致性
palette = QPalette()
palette.setColor(QPalette.Window, QColor(248, 250, 251))
palette.setColor(QPalette.WindowText, QColor(44, 62, 80))
palette.setColor(QPalette.Base, QColor(255, 255, 255))
palette.setColor(QPalette.AlternateBase, QColor(241, 244, 246))
palette.setColor(QPalette.ToolTipBase, QColor(255, 255, 255))
palette.setColor(QPalette.ToolTipText, QColor(44, 62, 80))
palette.setColor(QPalette.Text, QColor(44, 62, 80))
palette.setColor(QPalette.Button, QColor(66, 133, 244))
palette.setColor(QPalette.ButtonText, QColor(255, 255, 255))
palette.setColor(QPalette.BrightText, QColor(255, 255, 255))
palette.setColor(QPalette.Highlight, QColor(66, 133, 244))
palette.setColor(QPalette.HighlightedText, QColor(255, 255, 255))
QApplication.setPalette(palette)
def add_visual_effects(self):
"""添加视觉效果"""
try:
# 为主窗口添加阴影效果
shadow = QGraphicsDropShadowEffect()
shadow.setBlurRadius(20)
shadow.setXOffset(0)
shadow.setYOffset(5)
shadow.setColor(QColor(0, 0, 0, 40))
# 为输入框添加阴影
input_shadow = QGraphicsDropShadowEffect()
input_shadow.setBlurRadius(8)
input_shadow.setXOffset(0)
input_shadow.setYOffset(2)
input_shadow.setColor(QColor(0, 0, 0, 20))
self.token_input.setGraphicsEffect(input_shadow)
# 为按钮添加阴影
button_shadow = QGraphicsDropShadowEffect()
button_shadow.setBlurRadius(12)
button_shadow.setXOffset(0)
button_shadow.setYOffset(4)
button_shadow.setColor(QColor(66, 133, 244, 80))
self.login_btn.setGraphicsEffect(button_shadow)
# 设置对象名称以应用特定样式
self.token_input.setObjectName("tokenInput")
self.login_btn.setObjectName("loginButton")
print("[INFO] 视觉效果已添加")
except Exception as e:
print(f"[WARNING] 添加视觉效果失败: {e}")
def animate_success(self):
"""连接成功的动画效果"""
try:
# 按钮轻微放大动画
self.button_animation = QPropertyAnimation(self.login_btn, b"geometry")
original_rect = self.login_btn.geometry()
# 计算放大后的位置(居中放大)
expanded_rect = QRect(
original_rect.x() - 5,
original_rect.y() - 2,
original_rect.width() + 10,
original_rect.height() + 4
)
self.button_animation.setDuration(200)
self.button_animation.setStartValue(original_rect)
self.button_animation.setEndValue(expanded_rect)
self.button_animation.setEasingCurve(QEasingCurve.OutBack)
# 动画完成后恢复原始大小
def restore_size():
restore_animation = QPropertyAnimation(self.login_btn, b"geometry")
restore_animation.setDuration(150)
restore_animation.setStartValue(expanded_rect)
restore_animation.setEndValue(original_rect)
restore_animation.setEasingCurve(QEasingCurve.InBack)
restore_animation.start()
self.button_animation.finished.connect(restore_size)
self.button_animation.start()
print("[INFO] 成功动画已启动")
except Exception as e:
print(f"[WARNING] 动画效果失败: {e}")
def on_platform_connected(self, platform_name: str, all_platforms: list):
"""处理平台连接成功事件"""
try:
import time
self.connected_platforms = all_platforms.copy()
self.last_platform_connect_time = time.time()
# 短暂显示平台连接成功提示
self.status_label.setText(f"🟢 {platform_name}平台连接成功!")
self.status_label.setStyleSheet(
"color: #28a745; background: rgba(40, 167, 69, 0.15); border-radius: 12px; padding: 5px 10px; font-weight: bold;")
# 停止之前的定时器
if self.status_timer:
self.status_timer.stop()
self.status_timer = None
self.add_log(f"GUI收到平台连接通知: {platform_name}, 当前已连接: {', '.join(all_platforms)}", "INFO")
# 使用线程定时器,更可靠(资源消耗极小)
import threading
def delayed_update():
import time
time.sleep(3) # 等待3秒
# 使用QTimer.singleShot确保在主线程中执行GUI更新
QTimer.singleShot(0, self.delayed_platform_summary)
# 启动轻量级守护线程3秒后自动销毁
timer_thread = threading.Thread(target=delayed_update, daemon=True)
timer_thread.start()
self.add_log("3秒线程定时器已启动将自动切换到汇总显示", "INFO")
except Exception as e:
self.add_log(f"处理平台连接事件失败: {e}", "ERROR")
def on_token_error(self, error_content: str):
"""处理token错误 - 显示红色错误信息并停止所有操作"""
try:
self.add_log(f"Token验证失败: {error_content}", "ERROR")
# 在状态标签显示红色错误信息
self.status_label.setText(f"🔴 {error_content}")
self.status_label.setStyleSheet(
"color: #dc3545; background: rgba(220, 53, 69, 0.1); border-radius: 12px; padding: 5px 10px; font-weight: bold;")
# 重置按钮状态
self.login_btn.setEnabled(True)
self.login_btn.setText("重新连接")
self.login_btn.setObjectName("loginButton") # 恢复原始样式
# 清空已连接平台列表
self.connected_platforms.clear()
self.add_log("由于token无效已停止所有连接操作", "ERROR")
except Exception as e:
self.add_log(f"处理token错误失败: {e}", "ERROR")
def delayed_platform_summary(self):
"""定时器触发的汇总显示更新"""
try:
self.add_log("🎯 定时器触发!开始执行汇总显示更新", "INFO")
self.update_platform_summary()
self.add_log("🎯 定时器执行完成", "INFO")
except Exception as e:
self.add_log(f"定时器执行失败: {e}", "ERROR")
def check_and_update_summary(self):
"""检查是否应该更新汇总显示"""
try:
import time
elapsed = time.time() - self.last_platform_connect_time
self.add_log(f"检查汇总更新: 距离最后连接 {elapsed:.1f}", "INFO")
# 检查是否在最近1秒内还有新的平台连接
if elapsed >= 2.8: # 距离最后连接超过2.8秒
self.add_log("满足条件,开始更新汇总显示", "INFO")
self.update_platform_summary()
else:
# 如果还有新连接,再延迟一会儿
self.add_log(f"还需等待 {2.8 - elapsed:.1f} 秒,延迟更新", "INFO")
QTimer.singleShot(1000, self.check_and_update_summary)
except Exception as e:
self.add_log(f"检查汇总更新失败: {e}", "ERROR")
def update_platform_summary(self):
"""更新平台连接汇总显示"""
try:
self.add_log(f"开始更新汇总显示,当前连接平台: {self.connected_platforms}", "INFO")
if self.connected_platforms:
platforms_text = "".join(self.connected_platforms)
summary_text = f"🟢 已连接: {platforms_text}"
self.status_label.setText(summary_text)
self.status_label.setStyleSheet(
"color: #28a745; background: rgba(40, 167, 69, 0.1); border-radius: 12px; padding: 5px 10px;")
self.add_log(f"汇总显示已更新: {summary_text}", "INFO")
else:
self.status_label.setText("🟢 连接成功!等待平台指令...")
self.status_label.setStyleSheet(
"color: #28a745; background: rgba(40, 167, 69, 0.1); border-radius: 12px; padding: 5px 10px;")
self.add_log("已更新为等待平台指令状态", "INFO")
except Exception as e:
self.add_log(f"更新平台汇总显示失败: {e}", "ERROR")
def init_system_tray(self):
"""初始化系统托盘"""
# 检查系统是否支持托盘
if not QSystemTrayIcon.isSystemTrayAvailable():
QMessageBox.critical(None, "系统托盘",
"系统托盘不可用")
return
# 创建托盘图标
self.tray_icon = QSystemTrayIcon(self)
# 使用自定义的美观图标
try:
# 导入路径处理函数
from windows_taskbar_fix import get_resource_path
tray_icon_path = get_resource_path("static/ai_assistant_icon_16.png")
if os.path.exists(tray_icon_path):
from PyQt5.QtGui import QIcon
self.tray_icon.setIcon(QIcon(tray_icon_path))
print(f"[INFO] 已加载托盘图标: {tray_icon_path}")
else:
print(f"[WARNING] 托盘图标文件不存在: {tray_icon_path}")
# 备用方案:使用系统图标
self.tray_icon.setIcon(self.style().standardIcon(self.style().SP_ComputerIcon))
except Exception as e:
print(f"[WARNING] 加载托盘图标失败: {e}, 使用默认图标")
# 备用方案:使用系统图标
self.tray_icon.setIcon(self.style().standardIcon(self.style().SP_ComputerIcon))
# 创建托盘菜单
tray_menu = QMenu()
# 显示窗口动作
show_action = QAction("显示主窗口", self)
show_action.triggered.connect(self.show_window)
tray_menu.addAction(show_action)
# 分隔线
tray_menu.addSeparator()
# 退出动作
quit_action = QAction("退出程序", self)
quit_action.triggered.connect(self.quit_application)
tray_menu.addAction(quit_action)
# 设置托盘菜单
self.tray_icon.setContextMenu(tray_menu)
# 设置托盘提示
self.tray_icon.setToolTip("AI客服智能助手")
# 双击托盘图标显示窗口
self.tray_icon.activated.connect(self.tray_icon_activated)
# 显示托盘图标
self.tray_icon.show()
print("[INFO] 系统托盘已初始化")
def tray_icon_activated(self, reason):
"""托盘图标被激活时的处理"""
if reason == QSystemTrayIcon.DoubleClick:
self.show_window()
def show_window(self):
"""显示主窗口"""
self.show()
self.raise_()
self.activateWindow()
print("[INFO] 主窗口已显示")
def quit_application(self):
"""真正退出应用程序"""
print("[INFO] 正在退出应用程序...")
# 执行原来的关闭逻辑
try:
# 使用 WebSocket 管理器断开所有连接
from WebSocket.backend_singleton import get_websocket_manager
ws_manager = get_websocket_manager()
ws_manager.disconnect_all()
# 停止所有工作线程(向后兼容)
workers = []
if hasattr(self, 'jd_worker') and self.jd_worker:
workers.append(self.jd_worker)
if hasattr(self, 'douyin_worker') and self.douyin_worker:
workers.append(self.douyin_worker)
if hasattr(self, 'qian_niu_worker') and self.qian_niu_worker:
workers.append(self.qian_niu_worker)
if hasattr(self, 'pdd_worker') and self.pdd_worker:
workers.append(self.pdd_worker)
# 停止所有线程
for worker in workers:
if worker.isRunning():
worker.stop()
worker.quit()
worker.wait(1000)
# 强制关闭事件循环
for worker in workers:
if hasattr(worker, 'loop') and worker.loop and not worker.loop.is_closed():
worker.loop.close()
except Exception as e:
print(f"关闭时发生错误: {str(e)}")
finally:
# 隐藏托盘图标
if hasattr(self, 'tray_icon'):
self.tray_icon.hide()
# 退出应用程序
QApplication.quit()
def add_log(self, message, log_type="INFO"):
"""添加日志信息 - 只输出到终端"""
from datetime import datetime
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
# 根据日志类型设置颜色ANSI颜色码
colors = {
"ERROR": "\033[91m", # 红色
"SUCCESS": "\033[92m", # 绿色
"WARNING": "\033[93m", # 黄色
"INFO": "\033[94m", # 蓝色
"DEBUG": "\033[95m" # 紫色
}
reset = "\033[0m" # 重置颜色
color = colors.get(log_type, colors["INFO"])
log_entry = f"{color}[{timestamp}] [{log_type}] {message}{reset}"
print(log_entry)
def login(self):
"""处理连接逻辑"""
# 防止重复快速点击
import time
current_time = time.time()
if current_time - self.last_login_time < self.login_cooldown:
self.add_log(f"请等待 {self.login_cooldown} 秒后再试", "WARNING")
return
self.last_login_time = current_time
token = self.token_input.text().strip()
if not token:
self.add_log("请输入有效的连接令牌", "ERROR")
return
# 禁用连接按钮,防止重复点击
self.login_btn.setEnabled(False)
self.login_btn.setText("连接中...")
self.status_label.setText("正在连接服务...")
self.status_label.setStyleSheet("color: #ffc107;")
success = False
try:
# 使用 WebSocket 管理器处理连接
ws_manager = get_websocket_manager()
# 设置回调函数
ws_manager.set_callbacks(
log=self.add_log,
success=lambda: self.add_log("WebSocket连接管理器连接成功", "SUCCESS"),
error=lambda error: self.add_log(f"WebSocket连接管理器错误: {error}", "ERROR"),
platform_connected=self.on_platform_connected, # 新增:平台连接回调
token_error=self.on_token_error # 新增token错误回调
)
# 连接后端
success = ws_manager.connect_backend(token)
if success:
self.add_log("已启动WebSocket连接管理器", "SUCCESS")
self.status_label.setText("🟢 连接成功!等待平台指令...")
self.status_label.setStyleSheet(
"color: #28a745; background: rgba(40, 167, 69, 0.1); border-radius: 12px; padding: 5px 10px;")
self.login_btn.setText("✓ 已连接")
self.login_btn.setObjectName("connected")
self.login_btn.setStyleSheet(self.login_btn.styleSheet()) # 刷新样式
# 添加成功动画效果
self.animate_success()
else:
self.add_log("WebSocket连接管理器启动失败", "ERROR")
self.status_label.setText("🔴 连接失败,请检查令牌")
self.status_label.setStyleSheet(
"color: #dc3545; background: rgba(220, 53, 69, 0.1); border-radius: 12px; padding: 5px 10px;")
except Exception as e:
self.add_log(f"连接失败: {e}", "ERROR")
self.status_label.setText(f"🔴 连接失败: {str(e)}")
self.status_label.setStyleSheet(
"color: #dc3545; background: rgba(220, 53, 69, 0.1); border-radius: 12px; padding: 5px 10px;")
finally:
self.login_btn.setEnabled(True)
if not success:
self.login_btn.setText("重新连接")
self.login_btn.setObjectName("loginButton") # 恢复原始样式
def verify_token(self, token):
"""简化的令牌校验:非空即通过(实际校验由后端承担)"""
return bool(token)
def closeEvent(self, event):
"""窗口关闭事件处理 - 最小化到托盘"""
if hasattr(self, 'tray_icon') and self.tray_icon.isVisible():
# 首次最小化时显示提示消息
if not hasattr(self, '_tray_message_shown'):
self.tray_icon.showMessage(
"AI客服智能助手",
"程序已最小化到系统托盘。双击托盘图标可重新显示窗口。",
QSystemTrayIcon.Information,
3000
)
self._tray_message_shown = True
# 隐藏窗口而不是关闭
self.hide()
event.ignore()
print("[INFO] 窗口已最小化到系统托盘")
else:
# 如果托盘不可用,则正常退出
self.quit_application()
event.accept()
def main():
"""主函数,用于测试界面"""
app = QApplication(sys.argv)
# 设置应用程序属性
app.setApplicationName(config.WINDOW_TITLE)
app.setApplicationVersion(config.VERSION)
# 设置应用程序唯一ID重要避免和Python默认图标混淆
try:
import ctypes
# 设置应用程序用户模型ID让Windows识别为独立应用
ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID("ShuidropAI.CustomerService.1.0")
print("[INFO] 已设置应用程序唯一ID")
except Exception as e:
print(f"[WARNING] 设置应用程序ID失败: {e}")
# 创建主窗口
window = LoginWindow()
# 统一设置所有图标(使用任务栏修复模块)
try:
app_icon = setup_windows_taskbar_icon(app, window)
print("[INFO] 所有图标设置完成")
except Exception as e:
print(f"[WARNING] 图标设置失败: {e}")
# 备用方案:使用简单的图标设置
try:
# 导入路径处理函数
from windows_taskbar_fix import get_resource_path
icon_path = get_resource_path("static/ai_assistant_icon_32.png")
if os.path.exists(icon_path):
from PyQt5.QtGui import QIcon
backup_icon = QIcon(icon_path)
app.setWindowIcon(backup_icon)
window.setWindowIcon(backup_icon)
print(f"[INFO] 已使用备用图标: {icon_path}")
except Exception as e2:
print(f"[ERROR] 备用图标也设置失败: {e2}")
window.show() # 程序启动断点
# 运行应用程序
sys.exit(app.exec_())
if __name__ == '__main__':
main() # sd_acF0TisgfFOtsBm4ytqb17MQbcxuX9Vp 测试令牌(token)
# username = "KLD测试"
# password = "kld168168"
# taobao nickname = "tb420723827:redboat"