Files
macm1new/cursor_gui.py

880 lines
33 KiB
Python
Raw Permalink 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
import os
import json
from PyQt6.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout,
QLabel, QLineEdit, QPushButton, QTextEdit, QMessageBox,
QHBoxLayout, QDialog)
from PyQt6.QtCore import Qt, QTimer, QPropertyAnimation
from PyQt6.QtGui import QIcon, QPixmap
import traceback
import tempfile
# 创建临时日志文件
temp_log_file = os.path.join(tempfile.gettempdir(), 'cursor_helper_error.log')
def log_error(error_msg):
with open(temp_log_file, 'a', encoding='utf-8') as f:
f.write(f"{error_msg}\n")
try:
from logger import logging
import cursor_account_manager as backend
except Exception as e:
log_error(f"导入模块错误: {str(e)}\n{traceback.format_exc()}")
raise
# 添加密码管理类
class PasswordManager:
def __init__(self):
# 获取应用程序的实际运行路径
if getattr(sys, 'frozen', False):
# 如果是打包后的应用
if sys.platform == 'darwin':
# macOS下使用应用程序包内的Resources目录
bundle_dir = os.path.dirname(sys.executable)
app_root = os.path.abspath(os.path.join(bundle_dir, '..', 'Resources'))
self.app_support_dir = os.path.join(app_root, 'config')
else:
# 其他系统使用可执行文件所在目录
app_root = os.path.dirname(sys.executable)
self.app_support_dir = os.path.join(app_root, 'config')
else:
# 开发环境下使用用户目录
if sys.platform == 'darwin':
self.app_support_dir = os.path.expanduser('~/Library/Application Support/听泉Cursor助手')
else:
self.app_support_dir = os.path.expanduser('~/.听泉Cursor助手')
self.config_file = os.path.join(self.app_support_dir, 'config.json')
os.makedirs(self.app_support_dir, exist_ok=True)
logging.debug(f"密码管理器初始化,配置文件路径: {self.config_file}")
def save_password(self, password):
"""保存密码(这里可以添加简单加密)"""
try:
config = {'password': password}
with open(self.config_file, 'w', encoding='utf-8') as f:
json.dump(config, f)
logging.debug(f"密码保存{'成功' if password else '已清除'}")
return True
except Exception as e:
logging.error(f"保存密码失败: {str(e)}")
return False
def get_password(self):
"""获取保存的密码"""
try:
if os.path.exists(self.config_file):
with open(self.config_file, 'r', encoding='utf-8') as f:
config = json.load(f)
password = config.get('password')
logging.debug(f"读取到保存的密码: {'' if password else ''}")
return password
except Exception as e:
logging.error(f"读取密码失败: {str(e)}")
return None
class SuccessDialog(QDialog):
def __init__(self, message, parent=None):
super().__init__(parent)
self.setWindowTitle("激活成功")
self.setFixedSize(400, 300)
# 移除可能导致问题的窗口标志
self.setWindowFlags(Qt.WindowType.WindowStaysOnTopHint)
# 设置样式
self.setStyleSheet("""
QDialog {
background-color: #ffffff;
border: 1px solid #cccccc;
border-radius: 10px;
}
QLabel {
color: #333333;
font-size: 14px;
padding: 10px;
}
QLabel#titleLabel {
font-size: 24px;
font-weight: bold;
color: #0078d4;
}
QLabel#messageLabel {
font-size: 16px;
padding: 20px;
background-color: #f8f8f8;
border-radius: 8px;
}
QPushButton {
background-color: #0078d4;
color: white;
border: none;
padding: 12px 24px;
border-radius: 6px;
font-size: 16px;
min-width: 120px;
}
QPushButton:hover {
background-color: #006cbd;
}
QPushButton:pressed {
background-color: #005ba1;
}
""")
layout = QVBoxLayout()
layout.setSpacing(20)
layout.setContentsMargins(30, 30, 30, 30)
# 标题
title_label = QLabel("🎉 激活成功")
title_label.setObjectName("titleLabel")
title_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
layout.addWidget(title_label)
# 消息内容
message_label = QLabel(message)
message_label.setObjectName("messageLabel")
message_label.setAlignment(Qt.AlignmentFlag.AlignLeft)
message_label.setWordWrap(True)
layout.addWidget(message_label)
# 确定按钮
ok_button = QPushButton("确定")
ok_button.clicked.connect(self.accept)
ok_button.setCursor(Qt.CursorShape.PointingHandCursor)
# 按钮容器
button_container = QWidget()
button_layout = QHBoxLayout()
button_layout.addStretch()
button_layout.addWidget(ok_button)
button_layout.addStretch()
button_container.setLayout(button_layout)
layout.addWidget(button_container)
self.setLayout(layout)
# 5秒后自动关闭
QTimer.singleShot(5000, self.accept)
# 设置窗口位置为父窗口中心
if parent:
self.move(
parent.x() + (parent.width() - self.width()) // 2,
parent.y() + (parent.height() - self.height()) // 2
)
def showEvent(self, event):
"""窗口显示时的动画效果"""
self.setWindowOpacity(0.0)
self.animation = QPropertyAnimation(self, b"windowOpacity")
self.animation.setDuration(300) # 300ms
self.animation.setStartValue(0.0)
self.animation.setEndValue(1.0)
self.animation.start()
super().showEvent(event)
def closeEvent(self, event):
"""窗口关闭时的动画效果"""
self.animation = QPropertyAnimation(self, b"windowOpacity")
self.animation.setDuration(200) # 200ms
self.animation.setStartValue(1.0)
self.animation.setEndValue(0.0)
self.animation.finished.connect(self.close)
self.animation.start()
event.ignore()
class PasswordDialog(QDialog):
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowTitle("输入系统密码")
self.setFixedSize(450, 250) # 增加高度以容纳新控件
# 设置样式
self.setStyleSheet("""
QDialog {
background-color: #ffffff;
border: 1px solid #cccccc;
border-radius: 10px;
}
QLabel {
color: #333333;
font-size: 14px;
padding: 5px;
}
QLabel#tipLabel {
color: #666666;
font-size: 13px;
padding: 12px 15px;
background-color: #f8f8f8;
border-radius: 6px;
line-height: 20px;
min-height: 45px;
}
QLineEdit {
padding: 8px 12px;
border: 2px solid #cccccc;
border-radius: 6px;
background-color: white;
font-size: 14px;
min-height: 20px;
}
QLineEdit:focus {
border-color: #0078d4;
}
QPushButton {
background-color: #0078d4;
color: white;
border: none;
padding: 8px 20px;
border-radius: 6px;
font-size: 14px;
min-width: 80px;
}
QPushButton:hover {
background-color: #006cbd;
}
QPushButton:pressed {
background-color: #005ba1;
}
QPushButton#cancelButton {
background-color: #f0f0f0;
color: #333333;
}
QPushButton#cancelButton:hover {
background-color: #e0e0e0;
}
QPushButton#cancelButton:pressed {
background-color: #d0d0d0;
}
QCheckBox {
color: #333333;
font-size: 13px;
}
QCheckBox::indicator {
width: 18px;
height: 18px;
}
QCheckBox::indicator:unchecked {
border: 2px solid #cccccc;
background: white;
border-radius: 4px;
}
QCheckBox::indicator:checked {
border: 2px solid #0078d4;
background: #0078d4;
border-radius: 4px;
}
""")
layout = QVBoxLayout()
layout.setSpacing(8)
layout.setContentsMargins(20, 20, 20, 20)
# 提示文字
tip_label = QLabel("提示这里需要输入您的Mac电脑开机密码系统管理员密码\n用于执行需要管理员权限的操作。")
tip_label.setObjectName("tipLabel")
tip_label.setWordWrap(True)
layout.addWidget(tip_label)
# 密码输入框
self.password_input = QLineEdit()
self.password_input.setEchoMode(QLineEdit.EchoMode.Password)
self.password_input.setPlaceholderText("请输入Mac系统管理员密码")
layout.addWidget(self.password_input)
# 记住密码选项
from PyQt6.QtWidgets import QCheckBox
self.remember_checkbox = QCheckBox("记住密码")
self.remember_checkbox.setChecked(True) # 默认勾选
layout.addWidget(self.remember_checkbox)
# 按钮区域
button_layout = QHBoxLayout()
button_layout.setSpacing(8)
cancel_button = QPushButton("取消")
cancel_button.setObjectName("cancelButton")
cancel_button.setCursor(Qt.CursorShape.PointingHandCursor)
cancel_button.clicked.connect(self.reject)
cancel_button.setFixedWidth(80)
ok_button = QPushButton("确定")
ok_button.setCursor(Qt.CursorShape.PointingHandCursor)
ok_button.clicked.connect(self.accept)
ok_button.setFixedWidth(80)
button_layout.addStretch()
button_layout.addWidget(cancel_button)
button_layout.addWidget(ok_button)
layout.addSpacing(5)
layout.addLayout(button_layout)
self.setLayout(layout)
# 设置窗口位置为父窗口中心
if parent:
self.move(
parent.x() + (parent.width() - self.width()) // 2,
parent.y() + (parent.height() - self.height()) // 2
)
# 尝试加载保存的密码
self.password_manager = PasswordManager()
saved_password = self.password_manager.get_password()
if saved_password:
self.password_input.setText(saved_password)
def get_password(self):
password = self.password_input.text()
# 如果选择记住密码,则保存
if self.remember_checkbox.isChecked():
self.password_manager.save_password(password)
return password
class CursorGUI(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("听泉Cursor助手 v3.0.2")
self.setFixedSize(600, 600)
# 添加全局会员状态
self.is_member_active = False
# 设置定时器每3分钟检查一次会员状态
self.status_timer = QTimer(self)
self.status_timer.timeout.connect(self.check_member_status)
self.status_timer.start(180000) # 180000毫秒 = 3分钟
# 设置整体样式
self.setStyleSheet("""
QMainWindow {
background-color: #f5f5f5;
}
QWidget {
background-color: #f5f5f5;
color: #333333;
}
QLabel {
color: #333333;
font-size: 14px;
font-weight: bold;
}
QLineEdit {
padding: 8px;
border: 1px solid #cccccc;
border-radius: 4px;
background-color: white;
selection-background-color: #0078d4;
}
QTextEdit {
padding: 8px;
border: 1px solid #cccccc;
border-radius: 4px;
background-color: white;
selection-background-color: #0078d4;
}
QScrollBar:vertical {
border: none;
background: #f0f0f0;
width: 10px;
margin: 0px;
}
QScrollBar::handle:vertical {
background: #c0c0c0;
min-height: 30px;
border-radius: 5px;
}
QScrollBar::handle:vertical:hover {
background: #a0a0a0;
}
QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical {
height: 0px;
}
QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {
background: none;
}
QPushButton {
background-color: #0078d4;
color: white;
padding: 8px;
border: none;
border-radius: 4px;
font-size: 14px;
}
QPushButton:hover {
background-color: #006cbd;
}
QPushButton:pressed {
background-color: #005ba1;
}
""")
# 创建主窗口部件
main_widget = QWidget()
self.setCentralWidget(main_widget)
layout = QVBoxLayout()
layout.setSpacing(15) # 增加垂直间距
layout.setContentsMargins(20, 20, 20, 20) # 设置边距
main_widget.setLayout(layout)
# 设备ID显示区域
id_label = QLabel("设备识别码(勿动):")
id_layout = QHBoxLayout()
id_layout.setSpacing(10) # 设置水平间距
self.id_text = QLineEdit()
self.id_text.setReadOnly(True)
id_copy_btn = QPushButton("复制ID")
id_copy_btn.setFixedWidth(100)
id_copy_btn.clicked.connect(self.copy_device_id)
id_layout.addWidget(self.id_text)
id_layout.addWidget(id_copy_btn)
layout.addWidget(id_label)
layout.addLayout(id_layout)
# 会员状态显示区域
status_label = QLabel("会员状态")
self.status_text = QTextEdit()
self.status_text.setReadOnly(True)
self.status_text.setFixedHeight(150)
layout.addWidget(status_label)
layout.addWidget(self.status_text)
# 激活区域
activate_label = QLabel("激活会员,多个激活码叠加整体时长")
activate_layout = QHBoxLayout()
activate_layout.setSpacing(10) # 设置水平间距
self.activate_input = QLineEdit()
self.activate_input.setPlaceholderText("请输入激活码")
self.activate_btn = QPushButton("激活")
self.activate_btn.setFixedWidth(100)
self.activate_btn.clicked.connect(self.activate_account)
activate_layout.addWidget(self.activate_input)
activate_layout.addWidget(self.activate_btn)
layout.addWidget(activate_label)
layout.addLayout(activate_layout)
# 添加一些间距
layout.addSpacing(20)
# 功能按钮区域
button_style = """
QPushButton {
background-color: #0078d4;
color: white;
padding: 12px;
border: none;
border-radius: 6px;
font-size: 15px;
font-weight: bold;
margin: 5px 0;
}
QPushButton:hover {
background-color: #006cbd;
}
QPushButton:pressed {
background-color: #005ba1;
}
QPushButton:disabled {
background-color: #cccccc;
color: #666666;
}
"""
# 一键重置按钮
self.refresh_btn = QPushButton("刷新Cursor授权 (对话次数用完了提示limit时点一次)")
self.refresh_btn.setStyleSheet(button_style)
self.refresh_btn.setCursor(Qt.CursorShape.PointingHandCursor)
self.refresh_btn.clicked.connect(self.refresh_auth)
layout.addWidget(self.refresh_btn)
# 代用2按钮
self.patch_btn = QPushButton("突破0.45.x限制 (Too many free trials问题点这里)")
self.patch_btn.setStyleSheet(button_style)
self.patch_btn.setCursor(Qt.CursorShape.PointingHandCursor)
self.patch_btn.clicked.connect(self.install_patch)
layout.addWidget(self.patch_btn)
# 代用3按钮
self.update_btn = QPushButton("代用 3")
self.update_btn.setStyleSheet(button_style)
self.update_btn.setCursor(Qt.CursorShape.PointingHandCursor)
self.update_btn.clicked.connect(self.update_cursor)
layout.addWidget(self.update_btn)
# 初始化设备ID和状态
self.update_device_id()
self.update_status()
def update_device_id(self):
"""更新设备ID显示"""
try:
device_id = backend.get_mac_unique_id()
self.id_text.setText(device_id)
except Exception as e:
QMessageBox.warning(self, "错误", f"获取设备ID失败: {str(e)}")
def update_status(self):
"""更新会员状态显示"""
try:
account_manager = backend.CursorAccountManager()
success, status_data = account_manager.check_member_status()
# 获取设备信息
device_info = status_data.get("device_info", {}) if success else {}
# 设置状态文本和更新全局状态
if success and status_data.get("is_active"):
status_emoji = ""
status_text = "正常"
self.is_member_active = True
else:
status_emoji = ""
status_text = "未激活"
self.is_member_active = False
# 格式化显示文本
display_text = f"会员状态:{status_text} {status_emoji}\n"
display_text += f"到期时间:{status_data.get('expire_time', '--') if success else '--'}\n"
display_text += f"总天数:{status_data.get('total_days', 0) if success else 0}\n"
display_text += f"剩余天数:{status_data.get('days_left', 0) if success else 0}\n\n"
# 设备信息部分
display_text += "设备信息:\n"
display_text += f"系统:{device_info.get('system', sys.platform)}\n"
display_text += f"设备名:{device_info.get('device_name', '未知')}\n"
display_text += f"IP地址{device_info.get('ip', '--')}\n"
display_text += f"地理位置:{device_info.get('location', '--')}"
self.status_text.setText(display_text)
except Exception as e:
error_text = "会员状态:未激活 ❌\n"
error_text += "到期时间:--\n"
error_text += "总天数0天\n"
error_text += "剩余天数0天\n\n"
error_text += "设备信息:\n"
error_text += f"系统:{sys.platform}\n"
error_text += f"设备名:{backend.platform.node()}\n"
error_text += "IP地址--\n"
error_text += "地理位置:--"
self.status_text.setText(error_text)
def copy_device_id(self):
"""复制设备ID到剪贴板"""
clipboard = QApplication.clipboard()
clipboard.setText(self.id_text.text())
QMessageBox.information(self, "提示", "设备ID已复制到剪贴板")
def show_success_message(self, message):
"""显示统一的成功提示弹窗"""
msg = QMessageBox(self)
msg.setIcon(QMessageBox.Icon.Information)
msg.setWindowTitle("提示")
msg.setText(message)
msg.setStyleSheet("""
QMessageBox {
background-color: white;
}
QPushButton {
background-color: #0078d4;
color: white;
border: none;
padding: 8px 16px;
border-radius: 4px;
font-size: 14px;
min-width: 80px;
}
QPushButton:hover {
background-color: #006cbd;
}
""")
msg.exec()
def activate_account(self):
"""激活账号"""
code = self.activate_input.text().strip()
if not code:
logging.debug("激活码为空,显示警告")
QMessageBox.warning(self, "警告", "请输入激活码")
return
# 禁用激活按钮,显示加载状态
self.activate_btn.setEnabled(False)
self.activate_btn.setText("激活中...")
QApplication.processEvents()
try:
logging.debug(f"开始检查激活码: {code}")
account_manager = backend.CursorAccountManager()
success, message, account_info = account_manager.check_activation_code(code)
logging.debug(f"激活码检查结果: success={success}, message={message}, account_info={account_info}")
if success:
logging.debug("激活成功,开始更新状态")
# 更新状态显示和全局状态
self.update_status()
self.is_member_active = True
# 构建成功消息
success_message = (
f"🎉 激活成功!\n\n"
f"激活码:{code}\n"
f"到期时间:{account_info.get('expire_time', '--')}\n"
f"总天数:{account_info.get('total_days', 0)}\n"
f"剩余天数:{account_info.get('days_left', 0)}"
)
logging.debug(f"准备显示成功弹窗,消息内容: {success_message}")
# 使用统一的成功提示弹窗
self.show_success_message(success_message)
logging.debug("成功弹窗显示完成")
# 清空输入框
self.activate_input.clear()
logging.debug("激活流程完成")
else:
logging.debug(f"激活失败,显示错误消息: {message}")
QMessageBox.warning(self, "错误", message)
except Exception as e:
error_msg = f"激活过程出错: {str(e)}\n{traceback.format_exc()}"
logging.error(error_msg)
QMessageBox.warning(self, "错误", f"激活过程出错: {str(e)}")
finally:
# 恢复激活按钮状态
logging.debug("恢复激活按钮状态")
self.activate_btn.setEnabled(True)
self.activate_btn.setText("激活")
def show_activation_dialog(self):
"""显示统一的激活提示弹窗"""
msg = QMessageBox(self)
msg.setIcon(QMessageBox.Icon.Warning)
msg.setWindowTitle("提示")
msg.setText("请输入激活码")
# 设置详细信息
msg.setInformativeText("获取会员激活码,请通过以下方式:\n\n" +
"• 官方自助网站cursor.nosqli.com\n" +
"• 微信客服号behikcigxr\n" +
"• 闲鱼店铺xxx\n\n" +
"诚招代理商,欢迎加盟合作!")
# 添加按钮
visit_btn = msg.addButton("复制网站", QMessageBox.ButtonRole.ActionRole)
copy_wx_btn = msg.addButton("复制微信", QMessageBox.ButtonRole.ActionRole)
ok_btn = msg.addButton("确定", QMessageBox.ButtonRole.AcceptRole)
msg.setDefaultButton(ok_btn)
# 设置样式
msg.setStyleSheet("""
QMessageBox {
background-color: white;
}
QPushButton {
padding: 8px 16px;
border-radius: 4px;
font-size: 14px;
min-width: 80px;
}
QPushButton[text="确定"] {
background-color: #0078d4;
color: white;
border: none;
}
QPushButton[text="确定"]:hover {
background-color: #006cbd;
}
QPushButton[text="复制网站"], QPushButton[text="复制微信"] {
background-color: white;
border: 1px solid #0078d4;
color: #0078d4;
}
QPushButton[text="复制网站"]:hover, QPushButton[text="复制微信"]:hover {
background-color: #f0f9ff;
}
""")
# 显示对话框
clicked = msg.exec()
# 处理按钮点击
if msg.clickedButton() == visit_btn:
clipboard = QApplication.clipboard()
clipboard.setText("cursor.nosqli.com")
QMessageBox.information(self, "提示", "网址已复制到剪贴板")
elif msg.clickedButton() == copy_wx_btn:
clipboard = QApplication.clipboard()
clipboard.setText("behikcigxr")
QMessageBox.information(self, "提示", "微信号已复制到剪贴板")
return False
def check_member_status(self):
"""检查会员状态"""
try:
account_manager = backend.CursorAccountManager()
success, status_data = account_manager.check_member_status()
if success and status_data.get("is_active"):
self.is_member_active = True
return True
self.is_member_active = False
return False
except Exception as e:
logging.error(f"检查会员状态失败: {str(e)}")
self.is_member_active = False
return False
def refresh_auth(self):
"""刷新授权"""
# 检查会员状态,未激活则显示激活提示
if not self.is_member_active:
self.show_activation_dialog()
return
# 会员已激活,继续执行原有逻辑
while True:
# 先尝试获取保存的密码
password_manager = PasswordManager()
saved_password = password_manager.get_password()
if saved_password:
# 如果有保存的密码,直接使用
password = saved_password
else:
# 如果没有保存的密码,显示密码输入对话框
dialog = PasswordDialog(self)
if dialog.exec() == QDialog.DialogCode.Accepted:
password = dialog.get_password()
else:
QMessageBox.warning(self, "取消", "重置操作已取消")
return
# 显示加载状态
self.refresh_btn.setEnabled(False)
self.refresh_btn.setText("重置中...")
QApplication.processEvents()
try:
success, message = backend.reset_auth_with_password(password)
if success:
self.show_success_message("重置成功")
self.update_status()
break # 成功后退出循环
else:
# 密码错误,清除保存的密码
password_manager.save_password("")
QMessageBox.warning(self, "错误", message)
# 继续循环,重新输入密码
except Exception as e:
QMessageBox.warning(self, "错误", f"重置失败: {str(e)}")
break # 遇到其他错误时退出循环
finally:
# 恢复按钮状态
self.refresh_btn.setEnabled(True)
self.refresh_btn.setText("刷新Cursor授权 (对话次数用完了提示limit时点一次)")
def install_patch(self):
"""安装补丁"""
# 检查会员状态,未激活则显示激活提示
if not self.is_member_active:
self.show_activation_dialog()
return
# 会员已激活,继续执行原有逻辑
try:
# 检查版本
greater_than_0_45 = backend.check_cursor_version()
logging.debug(f"Cursor版本检查结果: {'> 0.45' if greater_than_0_45 else '<= 0.45'}")
while True: # 添加循环以支持重试
# 先尝试获取保存的密码
password_manager = PasswordManager()
saved_password = password_manager.get_password()
if saved_password:
logging.debug("使用保存的密码进行验证")
password = saved_password
else:
logging.debug("没有保存的密码,显示密码输入对话框")
dialog = PasswordDialog(self)
if dialog.exec() == QDialog.DialogCode.Accepted:
password = dialog.get_password()
logging.debug("用户输入了新密码")
else:
logging.debug("用户取消了密码输入")
QMessageBox.warning(self, "取消", "操作已取消")
return
# 显示加载状态
self.patch_btn.setEnabled(False)
self.patch_btn.setText("突破中...")
QApplication.processEvents()
try:
# 设置环境变量
os.environ['SUDO_PASSWORD'] = password
logging.debug("开始执行补丁安装...")
# 执行重置
backend.reset_machine_id(greater_than_0_45)
# 直接显示成功消息
logging.debug("补丁安装完成")
self.show_success_message("补丁安装成功")
self.update_status()
break # 成功后退出循环
except Exception as e:
logging.error(f"补丁安装过程发生错误: {str(e)}")
# 密码错误,清除保存的密码
password_manager.save_password("")
QMessageBox.warning(self, "错误", "密码验证失败,请重新输入")
continue # 继续循环,重新输入密码
finally:
# 恢复按钮状态
self.patch_btn.setEnabled(True)
self.patch_btn.setText("突破0.45.x限制 (Too many free trials问题点这里)")
except Exception as e:
logging.error(f"安装补丁失败: {str(e)}")
QMessageBox.warning(self, "错误", f"安装补丁失败: {str(e)}")
def update_cursor(self):
"""更新Cursor版本"""
# 检查会员状态,未激活则显示激活提示
if not self.is_member_active:
self.show_activation_dialog()
return
# 会员已激活,继续执行原有逻辑
QMessageBox.information(self, "提示", "更新功能开发中")
if __name__ == "__main__":
try:
# 记录启动信息
logging.info("=== 应用程序启动 ===")
logging.info(f"Python 版本: {sys.version}")
logging.info(f"操作系统: {sys.platform}")
app = QApplication(sys.argv)
window = CursorGUI()
window.show()
# 捕获未处理的异常
def handle_exception(exc_type, exc_value, exc_traceback):
error_msg = f"未捕获的异常:\n{traceback.format_exception(exc_type, exc_value, exc_traceback)}"
log_error(error_msg)
logging.error("未捕获的异常:", exc_info=(exc_type, exc_value, exc_traceback))
sys.excepthook = handle_exception
sys.exit(app.exec())
except Exception as e:
error_msg = f"程序启动失败: {str(e)}\n{traceback.format_exc()}"
log_error(error_msg)
logging.error(error_msg)
raise