1. 实现了基于PyQt5的GUI界面 2. 添加系统托盘功能,支持最小化到托盘 3. 修复了图标显示问题,包括窗口图标和任务栏图标 4. 优化了打包配置,支持PyInstaller打包 5. 版本更新到v3.3.1
277 lines
11 KiB
Python
277 lines
11 KiB
Python
import sys
|
||
from pathlib import Path
|
||
import logging
|
||
import os
|
||
from PIL import Image
|
||
from PyQt5.QtWidgets import (QMainWindow, QWidget, QVBoxLayout, QHBoxLayout,
|
||
QLabel, QLineEdit, QPushButton, QFrame, QTextEdit,
|
||
QMessageBox, QApplication, QSystemTrayIcon, QMenu)
|
||
from PyQt5.QtCore import Qt, QTimer
|
||
from PyQt5.QtGui import QIcon, QPixmap
|
||
|
||
sys.path.append(str(Path(__file__).parent.parent))
|
||
|
||
from utils.config import Config
|
||
from account_switcher import AccountSwitcher
|
||
|
||
def get_version():
|
||
try:
|
||
version_file = Path(__file__).parent.parent / 'version.txt'
|
||
with open(version_file, 'r', encoding='utf-8') as f:
|
||
return f.read().strip()
|
||
except Exception as e:
|
||
logging.error(f"读取版本号失败: {str(e)}")
|
||
return "未知版本"
|
||
|
||
class MainWindow(QMainWindow):
|
||
def __init__(self):
|
||
super().__init__()
|
||
self.config = Config()
|
||
self.switcher = AccountSwitcher()
|
||
|
||
version = get_version()
|
||
cursor_version = self.switcher.get_cursor_version()
|
||
self.setWindowTitle(f"听泉Cursor助手 v{version} (本机Cursor版本: {cursor_version})")
|
||
self.setMinimumSize(600, 500)
|
||
|
||
# 设置窗口图标
|
||
icon_path = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "icon", "two.ico")
|
||
if os.path.exists(icon_path):
|
||
window_icon = QIcon(icon_path)
|
||
if not window_icon.isNull():
|
||
self.setWindowIcon(window_icon)
|
||
logging.info(f"成功设置窗口图标: {icon_path}")
|
||
|
||
# 创建系统托盘图标
|
||
self.tray_icon = QSystemTrayIcon(self)
|
||
self.tray_icon.setIcon(self.windowIcon())
|
||
self.tray_icon.setToolTip("听泉Cursor助手")
|
||
|
||
# 创建托盘菜单
|
||
tray_menu = QMenu()
|
||
show_action = tray_menu.addAction("显示主窗口")
|
||
show_action.triggered.connect(self.show)
|
||
quit_action = tray_menu.addAction("退出")
|
||
quit_action.triggered.connect(QApplication.instance().quit)
|
||
|
||
# 设置托盘菜单
|
||
self.tray_icon.setContextMenu(tray_menu)
|
||
|
||
# 连接托盘图标的信号
|
||
self.tray_icon.activated.connect(self.on_tray_icon_activated)
|
||
|
||
# 显示托盘图标
|
||
self.tray_icon.show()
|
||
|
||
# 创建主窗口部件
|
||
central_widget = QWidget()
|
||
self.setCentralWidget(central_widget)
|
||
|
||
# 创建主布局
|
||
main_layout = QVBoxLayout(central_widget)
|
||
|
||
# 设备ID区域
|
||
device_frame = QFrame()
|
||
device_layout = QHBoxLayout(device_frame)
|
||
device_layout.addWidget(QLabel("设备识别码(勿动):"))
|
||
self.hardware_id_edit = QLineEdit(self.switcher.hardware_id)
|
||
self.hardware_id_edit.setReadOnly(True)
|
||
device_layout.addWidget(self.hardware_id_edit)
|
||
copy_btn = QPushButton("复制ID")
|
||
copy_btn.clicked.connect(self.copy_device_id)
|
||
device_layout.addWidget(copy_btn)
|
||
main_layout.addWidget(device_frame)
|
||
|
||
# 会员状态区域
|
||
status_frame = QFrame()
|
||
status_layout = QVBoxLayout(status_frame)
|
||
status_layout.addWidget(QLabel("会员状态"))
|
||
self.status_text = QTextEdit()
|
||
self.status_text.setReadOnly(True)
|
||
self.status_text.setMinimumHeight(100)
|
||
status_layout.addWidget(self.status_text)
|
||
main_layout.addWidget(status_frame)
|
||
|
||
# 激活区域
|
||
activation_frame = QFrame()
|
||
activation_layout = QVBoxLayout(activation_frame)
|
||
activation_layout.addWidget(QLabel("激活(叠加)会员,多个激活码可叠加整体时长"))
|
||
input_frame = QFrame()
|
||
input_layout = QHBoxLayout(input_frame)
|
||
input_layout.addWidget(QLabel("激活码:"))
|
||
self.activation_edit = QLineEdit()
|
||
input_layout.addWidget(self.activation_edit)
|
||
activate_btn = QPushButton("激活")
|
||
activate_btn.clicked.connect(self.activate_account)
|
||
input_layout.addWidget(activate_btn)
|
||
activation_layout.addWidget(input_frame)
|
||
main_layout.addWidget(activation_frame)
|
||
|
||
# 操作按钮区域
|
||
btn_frame = QFrame()
|
||
btn_layout = QVBoxLayout(btn_frame)
|
||
refresh_btn = QPushButton("刷新Cursor编辑器授权")
|
||
refresh_btn.clicked.connect(self.refresh_cursor_auth)
|
||
btn_layout.addWidget(refresh_btn)
|
||
bypass_btn = QPushButton("突破Cursor0.45.x限制")
|
||
bypass_btn.clicked.connect(self.dummy_function)
|
||
btn_layout.addWidget(bypass_btn)
|
||
disable_update_btn = QPushButton("禁用Cursor版本更新")
|
||
disable_update_btn.clicked.connect(self.disable_cursor_update)
|
||
btn_layout.addWidget(disable_update_btn)
|
||
main_layout.addWidget(btn_frame)
|
||
|
||
# 启动时检查一次状态
|
||
QTimer.singleShot(0, self.check_status)
|
||
|
||
def on_tray_icon_activated(self, reason):
|
||
"""处理托盘图标的点击事件"""
|
||
if reason == QSystemTrayIcon.DoubleClick:
|
||
self.show()
|
||
self.activateWindow()
|
||
|
||
def closeEvent(self, event):
|
||
"""重写关闭事件,最小化到托盘而不是退出"""
|
||
if hasattr(self, 'tray_icon') and self.tray_icon.isVisible():
|
||
event.ignore()
|
||
self.hide()
|
||
self.tray_icon.showMessage(
|
||
"听泉Cursor助手",
|
||
"程序已最小化到系统托盘",
|
||
QSystemTrayIcon.Information,
|
||
2000
|
||
)
|
||
else:
|
||
event.accept()
|
||
|
||
def copy_device_id(self):
|
||
"""复制设备ID到剪贴板"""
|
||
if not self.check_status():
|
||
return
|
||
QApplication.clipboard().setText(self.hardware_id_edit.text())
|
||
QMessageBox.information(self, "提示", "设备ID已复制到剪贴板")
|
||
|
||
def activate_account(self):
|
||
"""激活账号"""
|
||
code = self.activation_edit.text().strip()
|
||
if not code:
|
||
QMessageBox.warning(self, "提示", "请输入激活码")
|
||
return
|
||
|
||
try:
|
||
success, message, account_info = self.switcher.check_activation_code(code)
|
||
if success:
|
||
# 更新会员信息显示
|
||
self.update_status_display(account_info)
|
||
QMessageBox.information(self, "激活成功", "激活成功!\n" + message)
|
||
# 清空激活码输入框
|
||
self.activation_edit.clear()
|
||
else:
|
||
QMessageBox.critical(self, "激活失败", message)
|
||
|
||
# 激活后检查一次状态
|
||
self.check_status()
|
||
|
||
except Exception as e:
|
||
QMessageBox.critical(self, "错误", f"激活失败: {str(e)}")
|
||
# 出错后也检查状态
|
||
self.check_status()
|
||
|
||
def update_status_display(self, status_info: dict):
|
||
"""更新状态显示"""
|
||
# 打印API返回的原始数据
|
||
logging.info("=== API返回数据 ===")
|
||
logging.info(f"状态信息: {status_info}")
|
||
if 'activation_records' in status_info:
|
||
logging.info("激活记录:")
|
||
for record in status_info['activation_records']:
|
||
logging.info(f"- 记录: {record}")
|
||
|
||
# 更新状态文本
|
||
status_map = {
|
||
"active": "正常",
|
||
"inactive": "未激活",
|
||
"expired": "已过期"
|
||
}
|
||
status_text = status_map.get(status_info.get('status', 'inactive'), "未知")
|
||
|
||
# 构建状态文本
|
||
status_lines = [
|
||
f"会员状态:{status_text}",
|
||
f"到期时间:{status_info.get('expire_time', '')}",
|
||
f"总天数:{status_info.get('total_days', 0)}天",
|
||
f"剩余天数:{status_info.get('days_left', 0)}天"
|
||
]
|
||
|
||
# 如果有激活记录,显示最近一次激活信息
|
||
activation_records = status_info.get('activation_records', [])
|
||
if activation_records:
|
||
latest_record = activation_records[-1] # 获取最新的激活记录
|
||
device_info = latest_record.get('device_info', {})
|
||
|
||
status_lines.extend([
|
||
"",
|
||
"最近激活信息:",
|
||
f"激活码:{latest_record.get('code', '')}",
|
||
f"激活时间:{latest_record.get('activation_time', '')}",
|
||
f"增加天数:{latest_record.get('days', 0)}天",
|
||
"",
|
||
"设备信息:",
|
||
f"系统:{device_info.get('os', '')}",
|
||
f"设备名:{device_info.get('device_name', '')}",
|
||
f"IP地址:{device_info.get('ip', '')}",
|
||
f"地区:{device_info.get('location', '--')}"
|
||
])
|
||
|
||
# 更新状态文本
|
||
self.status_text.setPlainText("\n".join(status_lines))
|
||
|
||
def check_status(self):
|
||
"""检查会员状态"""
|
||
try:
|
||
status = self.switcher.get_member_status()
|
||
if status:
|
||
self.update_status_display(status)
|
||
return status.get('status') != 'inactive'
|
||
else:
|
||
# 更新为未激活状态
|
||
inactive_status = {
|
||
"hardware_id": self.switcher.hardware_id,
|
||
"expire_time": "",
|
||
"days_left": 0,
|
||
"total_days": 0,
|
||
"status": "inactive",
|
||
"activation_records": []
|
||
}
|
||
self.update_status_display(inactive_status)
|
||
return False
|
||
|
||
except Exception as e:
|
||
QMessageBox.critical(self, "错误", f"检查状态失败: {str(e)}")
|
||
return False
|
||
|
||
def refresh_cursor_auth(self):
|
||
"""刷新Cursor授权"""
|
||
try:
|
||
success, message = self.switcher.refresh_cursor_auth()
|
||
if success:
|
||
QMessageBox.information(self, "成功", message)
|
||
else:
|
||
QMessageBox.critical(self, "失败", message)
|
||
except Exception as e:
|
||
QMessageBox.critical(self, "错误", f"刷新授权失败: {str(e)}")
|
||
|
||
def disable_cursor_update(self):
|
||
"""禁用Cursor更新"""
|
||
try:
|
||
success, message = self.switcher.disable_cursor_update()
|
||
if success:
|
||
QMessageBox.information(self, "成功", message)
|
||
else:
|
||
QMessageBox.critical(self, "失败", message)
|
||
except Exception as e:
|
||
QMessageBox.critical(self, "错误", f"禁用更新失败: {str(e)}")
|
||
|
||
def dummy_function(self):
|
||
"""占位函数"""
|
||
QMessageBox.information(self, "提示", "此功能暂未实现") |