From 1b18e4b18931c6f3105dbab0103e6cc4e6a4b4c1 Mon Sep 17 00:00:00 2001 From: Leonmmcoset Date: Sun, 28 Sep 2025 19:19:36 +0800 Subject: [PATCH] =?UTF-8?q?feat(app=5Fdetail=5Fwindow):=20=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E5=BA=94=E7=94=A8=E9=A2=84=E8=A7=88=E5=9B=BE=E7=89=87?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=E5=B9=B6=E4=BC=98=E5=8C=96=E7=BC=93=E5=AD=98?= =?UTF-8?q?=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增HorizontalFlipView组件显示应用预览图片 - 实现图片下载缓存机制和自动清理功能 - 支持多种API返回格式的图片数据解析 - 添加详细的日志记录和错误处理 - 移除不再使用的云母效果相关代码 --- .../app_detail_window.cpython-312.pyc | Bin 44367 -> 59372 bytes .../__pycache__/leonapp_gui.cpython-312.pyc | Bin 136337 -> 148175 bytes pyqt5fluentdesign/app_detail_window.py | 301 +++++++++++++++++- pyqt5fluentdesign/config/config.json | 2 +- pyqt5fluentdesign/leonapp_gui.py | 71 +---- 5 files changed, 310 insertions(+), 64 deletions(-) diff --git a/pyqt5fluentdesign/__pycache__/app_detail_window.cpython-312.pyc b/pyqt5fluentdesign/__pycache__/app_detail_window.cpython-312.pyc index ec9d2b953a95e6a058193fe92b42d3dc54b2a935..01dcbda37363c51be48436a3415d486dfd387135 100644 GIT binary patch delta 17276 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 F{{iaRy?RykuBxu= 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 Aod5s; delta 20687 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 B3;h59 diff --git a/pyqt5fluentdesign/app_detail_window.py b/pyqt5fluentdesign/app_detail_window.py index 95230ab..af4a612 100644 --- a/pyqt5fluentdesign/app_detail_window.py +++ b/pyqt5fluentdesign/app_detail_window.py @@ -87,6 +87,9 @@ class AppDetailWindow(QMainWindow): self.app_id = app_id self.parent_window = parent + # 存储当前加载的本地缓存图片路径列表 + self.cached_image_paths = [] + # 设置窗口属性 self.setWindowTitle("应用详情") self.resize(850, 650) @@ -258,11 +261,13 @@ class AppDetailWindow(QMainWindow): result = self.api_client.make_request('getappinfo', {'id': self.app_id}) # 检查API调用是否成功 - if isinstance(result, dict) and 'success' in result and result['success']: - # 保存应用数据到实例属性 + if isinstance(result, dict) and 'data' in result and result['data'] is not None: + # 新API格式: {"status": "success", "data": {...}} + self.app_data = result['data'] + app_data = self.app_data + elif isinstance(result, dict) and 'success' in result and result['success']: + # 旧API格式兼容性支持 self.app_data = result['data'] - - # 为了保持向后兼容性,也保留局部变量 app_data = self.app_data else: # API调用失败,显示错误信息 @@ -287,7 +292,8 @@ class AppDetailWindow(QMainWindow): "created_at": "-", "downloads": "0", "rating": "0.0", - "category": "未知" + "category": "未知", + "images": [] } app_data = self.app_data @@ -363,6 +369,11 @@ class AppDetailWindow(QMainWindow): # 显示统计信息卡片 self.display_stats_card(app_data) + # 显示APP预览图片(如果有) + images = app_data.get('images', []) + if images and isinstance(images, list) and len(images) > 0: + self.display_app_images(images) + # 显示应用基本信息卡片 self.display_app_info_card(app_data) @@ -440,6 +451,286 @@ class AppDetailWindow(QMainWindow): self.scroll_layout.addWidget(stats_card) + def display_app_images(self, images): + """显示应用预览图片,使用QFluentWidgets的HorizontalFlipView组件""" + # 导入HorizontalFlipView组件 + from qfluentwidgets import HorizontalFlipView + import os + import requests + import uuid + from PyQt5.QtCore import Qt, QDir + from PyQt5.QtGui import QPixmap + from PyQt5.QtWidgets import QLabel + + # 打印传入的images数据 + logger.info(f"接收到的图片数据: {images}") + logger.info(f"图片数据类型: {type(images)}") + logger.info(f"图片数据长度: {len(images) if isinstance(images, list) else '不是列表'}") + + # 创建缓存文件夹 + cache_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'cache') + if not os.path.exists(cache_dir): + os.makedirs(cache_dir) + logger.info(f"创建缓存文件夹: {cache_dir}") + + # 创建图片预览卡片 + images_card = CardWidget() + images_card.setObjectName("ImagesCard") + images_card.setStyleSheet(""" + #ImagesCard { + background-color: white; + border-radius: 12px; + border: 1px solid rgba(0, 0, 0, 0.05); + } + """) + + card_layout = QVBoxLayout(images_card) + card_layout.setContentsMargins(20, 20, 20, 20) + card_layout.setSpacing(15) + + # 卡片标题和图标 + title_layout = QHBoxLayout() + title_icon = QLabel() + title_icon.setPixmap(FluentIcon.PHOTO.icon().pixmap(18, 18)) + title_icon.setStyleSheet("color: #9C27B0;") + + card_title = SubtitleLabel("应用预览") + card_title.setStyleSheet("font-size: 16px; font-weight: 600;") + + title_layout.addWidget(title_icon) + title_layout.addWidget(card_title) + title_layout.addStretch() + card_layout.addLayout(title_layout) + + # 创建HorizontalFlipView组件 + flip_view = HorizontalFlipView(self) + flip_view.setFixedSize(800, 450) + flip_view.setBorderRadius(12) + + # 准备图片URL列表 + valid_image_urls = [] + base_domain = 'http://leonmmcoset.jjxmm.win:8010' + logger.info(f"使用的基础域名: {base_domain}") + + # 验证并添加有效的图片URL + if isinstance(images, list): + logger.info(f"开始处理{len(images)}个图片项") + for index, image_data in enumerate(images): + logger.info(f"处理第{index+1}个图片项: {image_data}") + logger.info(f"图片项类型: {type(image_data)}") + + try: + if isinstance(image_data, dict): + logger.info(f"图片字典键: {image_data.keys()}") + + if 'image_path' in image_data: + image_path = image_data['image_path'] + logger.info(f"image_path值: {image_path}") + logger.info(f"image_path类型: {type(image_path)}") + + # 确保image_path是字符串类型 + if not isinstance(image_path, str): + logger.warning(f"图片路径不是字符串类型: {type(image_path)}") + continue + + # 构建完整的图片URL + logger.info(f"图片路径是否以http开头: {image_path.startswith(('http://', 'https://'))}") + logger.info(f"图片路径是否以/开头: {image_path.startswith('/')}") + + if not image_path.startswith(('http://', 'https://')): + # 处理路径格式 + if image_path.startswith('/'): + image_path = image_path[1:] + logger.info(f"修正后的路径: {image_path}") + image_url = f'{base_domain}/{image_path}' + else: + image_url = image_path + + logger.info(f"构建的完整URL: {image_url}") + + # 检查URL是否有效 + if image_url and len(image_url) > 0: + valid_image_urls.append(image_url) + logger.info(f"添加有效图片URL: {image_url}") + else: + logger.warning(f"图片项中没有'image_path'键") + else: + logger.warning(f"图片项不是字典类型: {type(image_data)}") + except Exception as e: + logger.error(f"处理图片数据时出错: {str(e)}") + else: + logger.error(f"images参数不是列表类型: {type(images)}") + + logger.info(f"最终有效图片URL列表: {valid_image_urls}") + logger.info(f"有效图片数量: {len(valid_image_urls)}") + + # 添加图片,如果没有有效图片则显示默认提示 + if valid_image_urls: + # 清空之前的缓存记录 + self.cached_image_paths = [] + + # 下载并显示图片 + successful_images = 0 + for index, image_url in enumerate(valid_image_urls): + try: + logger.info(f"准备处理第{index+1}张图片: {image_url}") + + # 生成唯一的缓存文件名 + file_extension = os.path.splitext(image_url)[1] or '.png' + cache_filename = f"{uuid.uuid4()}{file_extension}" + cache_file_path = os.path.join(cache_dir, cache_filename) + + logger.info(f"准备下载到缓存文件: {cache_file_path}") + + # 下载图片 + response = requests.get(image_url, timeout=10) + if response.status_code == 200: + logger.info(f"成功下载图片,状态码: 200") + + # 保存图片到本地缓存 + with open(cache_file_path, 'wb') as f: + f.write(response.content) + logger.info(f"图片已保存到: {cache_file_path}") + + # 记录缓存文件路径 + self.cached_image_paths.append(cache_file_path) + + # 尝试从本地文件加载图片 + pixmap = QPixmap() + if pixmap.load(cache_file_path): + logger.info(f"成功从本地文件加载图片: {cache_file_path}") + + # 使用HorizontalFlipView的addImage方法添加本地文件路径 + flip_view.addImage(cache_file_path) + successful_images += 1 + logger.info(f"成功添加第{index+1}张图片到显示组件") + else: + logger.error(f"无法加载本地缓存图片: {cache_file_path}") + # 如果加载失败,删除缓存文件 + if os.path.exists(cache_file_path): + os.remove(cache_file_path) + logger.info(f"删除无效的缓存文件: {cache_file_path}") + else: + logger.error(f"下载图片失败,状态码: {response.status_code}") + except Exception as e: + logger.error(f"处理图片 {image_url} 时出错: {str(e)}") + + logger.info(f"成功加载图片数量: {successful_images}") + logger.info(f"当前缓存图片路径列表: {self.cached_image_paths}") + + # 如果没有成功加载任何图片,显示错误信息 + if successful_images == 0: + from qfluentwidgets import BodyLabel + logger.warning("没有成功加载任何图片,显示错误提示") + error_label = BodyLabel("无法加载预览图片") + error_label.setAlignment(Qt.AlignCenter) + error_label.setStyleSheet("color: #e74c3c; font-size: 16px;") + error_label.setFixedSize(800, 450) + + flip_view_layout = QHBoxLayout() + flip_view_layout.addStretch() + flip_view_layout.addWidget(error_label) + flip_view_layout.addStretch() + + card_layout.addLayout(flip_view_layout) + else: + # 监听当前页码改变信号 + flip_view.currentIndexChanged.connect(lambda index: logger.info(f"当前页面:{index}")) + + # 居中显示HorizontalFlipView + flip_view_layout = QHBoxLayout() + flip_view_layout.addStretch() + flip_view_layout.addWidget(flip_view) + flip_view_layout.addStretch() + + card_layout.addLayout(flip_view_layout) + else: + # 没有有效图片时显示提示信息 + from qfluentwidgets import BodyLabel + logger.warning("没有有效图片URL,显示无图片提示") + no_image_label = BodyLabel("暂无预览图片") + no_image_label.setAlignment(Qt.AlignCenter) + no_image_label.setStyleSheet("color: #999; font-size: 16px;") + no_image_label.setFixedSize(800, 450) + + # 替换flip_view为提示标签 + flip_view_layout = QHBoxLayout() + flip_view_layout.addStretch() + flip_view_layout.addWidget(no_image_label) + flip_view_layout.addStretch() + + # 添加到卡片布局 + card_layout.addLayout(flip_view_layout) + + # 添加到主滚动布局 + self.scroll_layout.addWidget(images_card) + + def cleanup_cached_images(self): + """清理缓存的图片文件""" + logger.info(f"开始清理缓存图片,共{len(self.cached_image_paths)}个文件") + + try: + # 首先清理记录在cached_image_paths中的文件 + for image_path in self.cached_image_paths: + try: + if os.path.exists(image_path): + os.remove(image_path) + logger.info(f"成功删除缓存图片: {image_path}") + else: + logger.warning(f"缓存图片不存在: {image_path}") + except Exception as e: + logger.error(f"删除缓存图片失败 {image_path}: {str(e)}") + + # 清空缓存路径列表 + self.cached_image_paths = [] + + # 额外清理整个cache文件夹中的所有图片文件 + cache_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'cache') + if os.path.exists(cache_dir): + logger.info(f"开始清理整个缓存文件夹: {cache_dir}") + for filename in os.listdir(cache_dir): + file_path = os.path.join(cache_dir, filename) + try: + if os.path.isfile(file_path) and filename.endswith(('.png', '.jpg', '.jpeg', '.gif', '.bmp')): + os.remove(file_path) + logger.info(f"成功删除缓存文件夹中的文件: {filename}") + except Exception as e: + logger.error(f"删除缓存文件夹中的文件 {filename} 失败: {str(e)}") + + logger.info("缓存图片清理完成") + except Exception as e: + logger.error(f"缓存清理过程中出现错误: {str(e)}") + + def closeEvent(self, event): + """窗口关闭事件,清理缓存的图片""" + logger.info("窗口即将关闭,开始清理缓存图片") + self.cleanup_cached_images() + super().closeEvent(event) + + def __del__(self): + """析构函数,确保在对象被销毁时也能清理缓存""" + logger.info("对象即将销毁,执行最终缓存清理") + # 确保在应用意外退出时也能清理缓存 + try: + self.cleanup_cached_images() + except: + # 避免析构函数中抛出异常 + pass + + def _check_image_accessible(self, image_url): + """检查图片URL是否可访问""" + try: + # 发送HEAD请求检查图片是否可访问 + logger.info(f"检查图片URL可访问性: {image_url}") + response = requests.head(image_url, timeout=5) + logger.info(f"图片URL状态码: {response.status_code}") + return response.status_code == 200 + except Exception as e: + logger.error(f"检查图片URL可访问性失败: {str(e)}") + return False + + + def display_app_info_card(self, app_data): """显示应用基本信息卡片""" info_card = CardWidget() diff --git a/pyqt5fluentdesign/config/config.json b/pyqt5fluentdesign/config/config.json index 5c9892e..5444e8a 100644 --- a/pyqt5fluentdesign/config/config.json +++ b/pyqt5fluentdesign/config/config.json @@ -2,7 +2,7 @@ "General": { "AppOpenMethod": 1, "AutoOpenInstaller": false, - "MicaEffect": false + "MicaEffect": true }, "QFluentWidgets": { "ThemeColor": "#ff4169e1", diff --git a/pyqt5fluentdesign/leonapp_gui.py b/pyqt5fluentdesign/leonapp_gui.py index fbc3450..a1eaf1d 100644 --- a/pyqt5fluentdesign/leonapp_gui.py +++ b/pyqt5fluentdesign/leonapp_gui.py @@ -48,7 +48,7 @@ from qfluentwidgets import ( PrimaryPushButton, LineEdit, ComboBox, ProgressBar, TableWidget, ScrollArea, InfoBar, InfoBarPosition, NavigationInterface, NavigationItemPosition, FluentWindow, MSFluentWindow, FluentIcon, SimpleCardWidget, PrimaryPushSettingCard, - OptionsSettingCard, QConfig, ConfigItem, OptionsConfigItem, BoolValidator, OptionsValidator, qconfig, SplashScreen + OptionsSettingCard, QConfig, ConfigItem, OptionsConfigItem, BoolValidator, OptionsValidator, qconfig, SplashScreen, NavigationAvatarWidget ) from qfluentwidgets import FluentTranslator from app_detail_window import AppDetailWindow @@ -69,11 +69,7 @@ class AppConfig(QConfig): OptionsValidator([0, 1]) ) - # 云母效果 - mica_effect = OptionsConfigItem( - "General", "MicaEffect", True, - OptionsValidator([True, False]) - ) + # 配置项已删除云母效果 # 创建配置文件目录 config_dir = os.path.join(os.path.dirname(__file__), "config") @@ -2630,9 +2626,14 @@ class SettingsTab(QWidget): # 创建主布局 self.main_layout = QVBoxLayout(self) - # 创建滚动区域 + # 创建滚动区域并设置无样式 self.scroll_area = ScrollArea(self) self.scroll_area.setWidgetResizable(True) + # 设置无样式但保留内容显示 + self.scroll_area.setFrameShape(QFrame.NoFrame) + self.scroll_area.setStyleSheet("background-color: transparent; border: none;") + self.scroll_area.verticalScrollBar().setStyleSheet("QScrollBar:vertical { width: 0px; }") + self.scroll_area.horizontalScrollBar().setStyleSheet("QScrollBar:horizontal { height: 0px; }") # 创建滚动内容控件 self.scroll_content = QWidget() @@ -2682,25 +2683,9 @@ class SettingsTab(QWidget): general_layout.addWidget(self.app_open_method_option) - # 添加云母效果选项 - self.mica_effect_option = OptionsSettingCard( - icon=FluentIcon.INFO, - title="启用云母效果", - content="开启窗口的云母效果,提供更现代的视觉体验", - texts=["是", "否"], - configItem=app_config.mica_effect, - parent=general_card - ) + # 已删除云母效果选项 - # 连接信号 - self.mica_effect_option.optionChanged.connect(self.on_mica_effect_changed) - - general_layout.addWidget(self.mica_effect_option) - - # 连接信号 - self.mica_effect_option.optionChanged.connect(self.on_mica_effect_changed) - - # 已经在前面添加过了,这里不需要重复添加 + # 已经删除了云母效果选项 # 添加查看日志按钮 general_layout.addSpacing(20) @@ -2729,23 +2714,7 @@ class SettingsTab(QWidget): """应用打开方式设置变更处理""" app_config.app_open_method = index - def on_mica_effect_changed(self, index): - """云母效果设置变更处理""" - app_config.mica_effect = (index == 0) - # 显示提示,告知用户需要重启应用才能生效 - from qfluentwidgets import InfoBar, InfoBarPosition - from PyQt5.QtWidgets import QApplication - - # 创建Sweet Alert风格的提示 - InfoBar.warning( - title="需要重启应用", - content="云母效果设置已更新,需要重启应用才能生效。", - orient=Qt.Horizontal, - isClosable=True, - position=InfoBarPosition.TOP_RIGHT, - duration=3000, - parent=self - ) + # 已删除云母效果处理方法 def show_logs(self): """显示应用日志""" @@ -2972,22 +2941,8 @@ class LeonAppGUI(MSFluentWindow): if os.path.exists(icon_path): self.setWindowIcon(QIcon(icon_path)) - # 根据配置启用云母效果 - from qfluentwidgets import isDarkTheme - if app_config.mica_effect: - # 优先尝试设置云母效果 - if hasattr(self, 'setMicaEffect'): - self.setMicaEffect(True) - # 如果没有直接的云母效果方法,尝试使用亚克力效果作为替代 - elif hasattr(self, 'setAcrylicEffect'): - self.setAcrylicEffect(True) - # 如果都没有,使用窗口透明度作为最后的替代 - elif hasattr(self, 'setWindowOpacity'): - self.setWindowOpacity(0.95) - else: - # 禁用效果,恢复为完全不透明 - if hasattr(self, 'setWindowOpacity'): - self.setWindowOpacity(1.0) + # 已删除云母效果相关代码 + # 保持窗口默认不透明状态 # 初始化UI self.init_ui()