mirror of
https://github.com/goldenfishs/MRobot.git
synced 2026-03-31 21:07:14 +08:00
v1.0.6
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import os
|
||||
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout
|
||||
from PyQt5.QtCore import Qt, QUrl, QTimer
|
||||
from PyQt5.QtGui import QDesktopServices
|
||||
@@ -12,8 +13,9 @@ from qfluentwidgets import (
|
||||
from .function_fit_interface import FunctionFitInterface
|
||||
from app.tools.check_update import check_update
|
||||
from app.tools.auto_updater import AutoUpdater, check_update_availability
|
||||
from app.tools.update_check_thread import UpdateCheckThread
|
||||
|
||||
__version__ = "1.0.2"
|
||||
__version__ = "1.0.6"
|
||||
|
||||
class AboutInterface(QWidget):
|
||||
def __init__(self, parent=None):
|
||||
@@ -32,13 +34,7 @@ class AboutInterface(QWidget):
|
||||
layout.setAlignment(Qt.AlignmentFlag.AlignTop)
|
||||
layout.setContentsMargins(20, 30, 20, 20)
|
||||
|
||||
# 页面标题
|
||||
title = SubtitleLabel("MRobot 帮助页面", self)
|
||||
title.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
layout.addWidget(title)
|
||||
layout.addSpacing(10)
|
||||
|
||||
# 版本信息卡片 - 学习AI界面风格
|
||||
# 版本信息卡片
|
||||
version_card = ElevatedCardWidget()
|
||||
version_layout = QVBoxLayout(version_card)
|
||||
version_layout.setContentsMargins(24, 20, 24, 20)
|
||||
@@ -57,7 +53,7 @@ class AboutInterface(QWidget):
|
||||
text="检查更新",
|
||||
icon=FluentIcon.SYNC,
|
||||
title="检查更新",
|
||||
content="检查是否有新版本可用",
|
||||
content="检查是否有新版本可用(需要能够连接github)",
|
||||
)
|
||||
self.check_update_card.clicked.connect(self.check_for_updates)
|
||||
layout.addWidget(self.check_update_card)
|
||||
@@ -119,7 +115,8 @@ class AboutInterface(QWidget):
|
||||
|
||||
self.notes_display = TextEdit()
|
||||
self.notes_display.setReadOnly(True)
|
||||
self.notes_display.setFixedHeight(200)
|
||||
self.notes_display.setMaximumHeight(200)
|
||||
self.notes_display.setMinimumHeight(80)
|
||||
self.notes_display.setText("暂无更新说明")
|
||||
layout.addWidget(self.notes_display)
|
||||
|
||||
@@ -135,6 +132,11 @@ class AboutInterface(QWidget):
|
||||
self.progress_bar.setValue(0)
|
||||
progress_layout.addWidget(self.progress_bar)
|
||||
|
||||
# 详细下载信息
|
||||
self.download_info = BodyLabel("")
|
||||
self.download_info.setWordWrap(True)
|
||||
progress_layout.addWidget(self.download_info)
|
||||
|
||||
self.progress_widget.hide()
|
||||
layout.addWidget(self.progress_widget)
|
||||
|
||||
@@ -170,16 +172,58 @@ class AboutInterface(QWidget):
|
||||
def _perform_check(self):
|
||||
"""执行更新检查"""
|
||||
try:
|
||||
# 获取最新版本信息(包括当前版本的详细信息)
|
||||
latest_info = self._get_latest_release_info()
|
||||
|
||||
# 检查是否有可用更新
|
||||
self.update_info = check_update_availability(__version__)
|
||||
|
||||
if self.update_info:
|
||||
self._show_update_available()
|
||||
else:
|
||||
self._show_no_update()
|
||||
self._show_no_update(latest_info)
|
||||
|
||||
except Exception as e:
|
||||
self._show_error(f"检查更新失败: {str(e)}")
|
||||
|
||||
def _get_latest_release_info(self):
|
||||
"""获取最新发布信息,不论版本是否需要更新"""
|
||||
try:
|
||||
import requests
|
||||
from packaging.version import parse as vparse
|
||||
|
||||
url = f"https://api.github.com/repos/goldenfishs/MRobot/releases/latest"
|
||||
response = requests.get(url, timeout=10)
|
||||
|
||||
if response.status_code == 200:
|
||||
release_data = response.json()
|
||||
latest_version = release_data["tag_name"].lstrip("v")
|
||||
|
||||
# 获取下载URL和文件大小
|
||||
assets = release_data.get('assets', [])
|
||||
asset_size = 0
|
||||
download_url = None
|
||||
|
||||
if assets:
|
||||
# 选择第一个资源文件
|
||||
asset = assets[0]
|
||||
asset_size = asset.get('size', 0)
|
||||
download_url = asset.get('browser_download_url', '')
|
||||
|
||||
return {
|
||||
'version': latest_version,
|
||||
'release_notes': release_data.get('body', '暂无更新说明'),
|
||||
'release_date': release_data.get('published_at', ''),
|
||||
'asset_size': asset_size,
|
||||
'download_url': download_url
|
||||
}
|
||||
else:
|
||||
return None
|
||||
|
||||
except Exception as e:
|
||||
print(f"获取发布信息失败: {e}")
|
||||
return None
|
||||
|
||||
def _show_update_available(self):
|
||||
"""显示发现更新"""
|
||||
# 更新按钮状态
|
||||
@@ -216,11 +260,43 @@ class AboutInterface(QWidget):
|
||||
duration=3000
|
||||
)
|
||||
|
||||
def _show_no_update(self):
|
||||
"""显示无更新"""
|
||||
def _show_no_update(self, latest_info=None):
|
||||
"""显示无更新,但展示最新版本信息"""
|
||||
self.check_update_card.setEnabled(True)
|
||||
self.check_update_card.setContent("已是最新版本")
|
||||
|
||||
# 如果有最新版本信息,显示详情卡片
|
||||
if latest_info:
|
||||
self.update_info_card.show()
|
||||
|
||||
# 显示版本信息(当前版本就是最新版本)
|
||||
self.latest_version_label.setText(f"v{__version__}")
|
||||
|
||||
# 设置文件信息
|
||||
asset_size = latest_info.get('asset_size', 0)
|
||||
file_size = self._format_file_size(asset_size)
|
||||
self.file_size_label.setText(f"文件大小: {file_size}")
|
||||
|
||||
# 设置发布时间
|
||||
release_date = latest_info.get('release_date', '')
|
||||
formatted_date = self._format_date(release_date)
|
||||
self.release_date_label.setText(f"发布时间: {formatted_date}")
|
||||
|
||||
# 设置更新说明
|
||||
notes = latest_info.get('release_notes', '暂无更新说明')
|
||||
self.notes_display.setText(notes[:500] + ('...' if len(notes) > 500 else ''))
|
||||
|
||||
# 修改标题和按钮
|
||||
self.update_title.setText("版本信息")
|
||||
self.update_btn.setText("手动下载")
|
||||
self.update_btn.setIcon(FluentIcon.DOWNLOAD)
|
||||
self.update_btn.setEnabled(True)
|
||||
self.manual_btn.setEnabled(True)
|
||||
|
||||
# 连接手动下载功能
|
||||
self.update_btn.clicked.disconnect()
|
||||
self.update_btn.clicked.connect(self.open_manual_download)
|
||||
|
||||
InfoBar.info(
|
||||
title="已是最新版本",
|
||||
content="当前已是最新版本,无需更新。",
|
||||
@@ -252,9 +328,10 @@ class AboutInterface(QWidget):
|
||||
self.update_btn.setEnabled(False)
|
||||
self.manual_btn.setEnabled(False)
|
||||
|
||||
# 启动更新器
|
||||
# 启动更新器(使用简化的单线程下载)
|
||||
self.updater = AutoUpdater(__version__)
|
||||
self.updater.signals.progress_changed.connect(self.update_progress)
|
||||
self.updater.signals.download_progress.connect(self.update_download_progress)
|
||||
self.updater.signals.status_changed.connect(self.update_status)
|
||||
self.updater.signals.error_occurred.connect(self.update_error)
|
||||
self.updater.signals.update_completed.connect(self.update_completed)
|
||||
@@ -266,6 +343,29 @@ class AboutInterface(QWidget):
|
||||
"""更新进度"""
|
||||
self.progress_bar.setValue(value)
|
||||
|
||||
def update_download_progress(self, downloaded: int, total: int, speed: float, remaining: float):
|
||||
"""更新下载进度详情"""
|
||||
if total > 0:
|
||||
downloaded_str = self._format_bytes(downloaded)
|
||||
total_str = self._format_bytes(total)
|
||||
percentage = (downloaded / total) * 100
|
||||
|
||||
info_text = f"已下载: {downloaded_str} / {total_str} ({percentage:.1f}%)"
|
||||
|
||||
self.download_info.setText(info_text)
|
||||
|
||||
def _format_bytes(self, size_bytes: int) -> str:
|
||||
"""格式化字节大小"""
|
||||
if size_bytes == 0:
|
||||
return "0 B"
|
||||
|
||||
size = float(size_bytes)
|
||||
for unit in ['B', 'KB', 'MB', 'GB']:
|
||||
if size < 1024.0:
|
||||
return f"{size:.1f} {unit}"
|
||||
size /= 1024.0
|
||||
return f"{size:.1f} TB"
|
||||
|
||||
def update_status(self, status: str):
|
||||
"""更新状态"""
|
||||
self.progress_label.setText(status)
|
||||
@@ -276,34 +376,106 @@ class AboutInterface(QWidget):
|
||||
self.update_btn.setEnabled(True)
|
||||
self.manual_btn.setEnabled(True)
|
||||
|
||||
InfoBar.error(
|
||||
title="更新失败",
|
||||
content=error_msg,
|
||||
parent=self,
|
||||
position=InfoBarPosition.TOP,
|
||||
duration=4000
|
||||
)
|
||||
# 如果是平台兼容性问题,提供更友好的提示
|
||||
if "Windows 安装程序" in error_msg and "当前系统是" in error_msg:
|
||||
InfoBar.warning(
|
||||
title="平台不兼容",
|
||||
content="检测到 Windows 安装程序,请点击'手动下载'获取适合 macOS 的版本",
|
||||
parent=self,
|
||||
position=InfoBarPosition.TOP,
|
||||
duration=6000
|
||||
)
|
||||
else:
|
||||
InfoBar.error(
|
||||
title="更新失败",
|
||||
content=error_msg,
|
||||
parent=self,
|
||||
position=InfoBarPosition.TOP,
|
||||
duration=4000
|
||||
)
|
||||
|
||||
def update_completed(self):
|
||||
"""更新完成"""
|
||||
self.progress_label.setText("更新完成,准备重启...")
|
||||
def update_completed(self, file_path=None):
|
||||
"""更新完成 - 显示下载文件位置"""
|
||||
print(f"update_completed called with file_path: {file_path}") # 调试输出
|
||||
|
||||
self.progress_label.setText("下载完成!")
|
||||
self.progress_bar.setValue(100)
|
||||
|
||||
InfoBar.success(
|
||||
title="更新完成",
|
||||
content="更新安装完成,程序将在3秒后重启",
|
||||
parent=self,
|
||||
position=InfoBarPosition.TOP,
|
||||
duration=3000
|
||||
)
|
||||
# 重新启用按钮
|
||||
self.update_btn.setEnabled(True)
|
||||
self.manual_btn.setEnabled(True)
|
||||
|
||||
# 延迟重启
|
||||
QTimer.singleShot(3000, self._restart_app)
|
||||
if file_path and os.path.exists(file_path):
|
||||
print(f"File exists: {file_path}") # 调试输出
|
||||
InfoBar.success(
|
||||
title="下载完成",
|
||||
content="安装文件已下载完成,点击下方按钮打开文件位置",
|
||||
parent=self,
|
||||
position=InfoBarPosition.TOP,
|
||||
duration=5000
|
||||
)
|
||||
|
||||
# 添加打开文件夹按钮
|
||||
self._add_open_folder_button(file_path)
|
||||
else:
|
||||
print(f"File does not exist or file_path is None: {file_path}") # 调试输出
|
||||
InfoBar.success(
|
||||
title="下载完成",
|
||||
content="文件下载完成",
|
||||
parent=self,
|
||||
position=InfoBarPosition.TOP,
|
||||
duration=3000
|
||||
)
|
||||
|
||||
def _add_open_folder_button(self, file_path):
|
||||
"""添加打开文件夹按钮"""
|
||||
def open_file_location():
|
||||
folder_path = os.path.dirname(file_path)
|
||||
# 在 macOS 上使用 Finder 打开文件夹
|
||||
QDesktopServices.openUrl(QUrl.fromLocalFile(folder_path))
|
||||
|
||||
InfoBar.info(
|
||||
title="已打开文件夹",
|
||||
content=f"文件位置: {folder_path}",
|
||||
parent=self,
|
||||
position=InfoBarPosition.TOP,
|
||||
duration=3000
|
||||
)
|
||||
|
||||
# 直接替换更新按钮的文本和功能
|
||||
self.update_btn.setText("打开文件位置")
|
||||
self.update_btn.setIcon(FluentIcon.FOLDER)
|
||||
# 断开原有连接
|
||||
self.update_btn.clicked.disconnect()
|
||||
# 连接新功能
|
||||
self.update_btn.clicked.connect(open_file_location)
|
||||
|
||||
# 修改取消按钮为清理按钮
|
||||
self.cancel_btn.setText("清理临时文件")
|
||||
self.cancel_btn.setIcon(FluentIcon.DELETE)
|
||||
self.cancel_btn.clicked.disconnect()
|
||||
|
||||
def cleanup_temp_files():
|
||||
if self.updater:
|
||||
self.updater.cleanup()
|
||||
InfoBar.success(
|
||||
title="已清理",
|
||||
content="临时文件已清理完成",
|
||||
parent=self,
|
||||
position=InfoBarPosition.TOP,
|
||||
duration=2000
|
||||
)
|
||||
# 重置界面
|
||||
self.update_info_card.hide()
|
||||
self.check_update_card.setContent("检查是否有新版本可用")
|
||||
|
||||
self.cancel_btn.clicked.connect(cleanup_temp_files)
|
||||
|
||||
def cancel_update(self):
|
||||
"""取消更新"""
|
||||
if self.updater and self.updater.isRunning():
|
||||
if hasattr(self, 'updater') and self.updater and self.updater.isRunning():
|
||||
self.updater.cancel_update()
|
||||
self.updater.cleanup()
|
||||
|
||||
self.update_info_card.hide()
|
||||
self.check_update_card.setContent("检查是否有新版本可用")
|
||||
|
||||
Reference in New Issue
Block a user