feat(gui): 主页功能完善
This commit is contained in:
@@ -515,12 +515,15 @@ class AppConfig:
|
|||||||
data["drop_statistics"][current_stage] = stage_drops
|
data["drop_statistics"][current_stage] = stage_drops
|
||||||
|
|
||||||
current_stage = drop_match.group(1)
|
current_stage = drop_match.group(1)
|
||||||
|
if current_stage == "WE":
|
||||||
|
current_stage = "剿灭模式"
|
||||||
stage_drops = {}
|
stage_drops = {}
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if current_stage:
|
if current_stage:
|
||||||
item_match: List[str] = re.findall(
|
item_match: List[str] = re.findall(
|
||||||
r"([\u4e00-\u9fa5]+)\s*:\s*([\d,]+)(?:\s*\(\+[\d,]+\))?", line
|
r"([\u4e00-\u9fa5A-Za-z0-9\-]+)\s*:\s*([\d,]+)(?:\s*\(\+[\d,]+\))?",
|
||||||
|
line,
|
||||||
)
|
)
|
||||||
for item, total in item_match:
|
for item, total in item_match:
|
||||||
# 解析数值时去掉逗号 (如 2,160 -> 2160)
|
# 解析数值时去掉逗号 (如 2,160 -> 2160)
|
||||||
@@ -745,6 +748,12 @@ class AppConfig:
|
|||||||
class GlobalConfig(QConfig):
|
class GlobalConfig(QConfig):
|
||||||
"""全局配置"""
|
"""全局配置"""
|
||||||
|
|
||||||
|
function_HomeImageMode = OptionsConfigItem(
|
||||||
|
"Function",
|
||||||
|
"HomeImageMode",
|
||||||
|
"默认",
|
||||||
|
OptionsValidator(["默认", "自定义", "主题图像"]),
|
||||||
|
)
|
||||||
function_HistoryRetentionTime = OptionsConfigItem(
|
function_HistoryRetentionTime = OptionsConfigItem(
|
||||||
"Function", "HistoryRetentionTime", 0, OptionsValidator([7, 15, 30, 60, 0])
|
"Function", "HistoryRetentionTime", 0, OptionsValidator([7, 15, 30, 60, 0])
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -463,14 +463,22 @@ class IconButton(TransparentToolButton):
|
|||||||
class Banner(QWidget):
|
class Banner(QWidget):
|
||||||
"""展示带有圆角的固定大小横幅小部件"""
|
"""展示带有圆角的固定大小横幅小部件"""
|
||||||
|
|
||||||
def __init__(self, image_path: str, parent=None):
|
def __init__(self, image_path: str = None, parent=None):
|
||||||
QWidget.__init__(self, parent)
|
QWidget.__init__(self, parent)
|
||||||
|
self.image_path = None
|
||||||
|
self.banner_image = None
|
||||||
|
self.scaled_image = None
|
||||||
|
|
||||||
|
if image_path:
|
||||||
|
self.set_banner_image(image_path)
|
||||||
|
|
||||||
|
def set_banner_image(self, image_path: str):
|
||||||
|
"""设置横幅图片"""
|
||||||
self.image_path = image_path
|
self.image_path = image_path
|
||||||
self.banner_image = self.load_banner_image(image_path)
|
self.banner_image = self.load_banner_image(image_path)
|
||||||
self.scaled_image = None
|
|
||||||
self.update_scaled_image()
|
self.update_scaled_image()
|
||||||
|
|
||||||
def load_banner_image(self, image_path: str):
|
def load_banner_image(self, image_path: str) -> QPixmap:
|
||||||
"""加载横幅图片,或创建渐变备用图片"""
|
"""加载横幅图片,或创建渐变备用图片"""
|
||||||
if os.path.isfile(image_path):
|
if os.path.isfile(image_path):
|
||||||
return QPixmap(image_path)
|
return QPixmap(image_path)
|
||||||
|
|||||||
222
app/ui/home.py
222
app/ui/home.py
@@ -32,12 +32,19 @@ from PySide6.QtWidgets import (
|
|||||||
QHBoxLayout,
|
QHBoxLayout,
|
||||||
QSpacerItem,
|
QSpacerItem,
|
||||||
QSizePolicy,
|
QSizePolicy,
|
||||||
|
QFileDialog,
|
||||||
)
|
)
|
||||||
from PySide6.QtCore import Qt, QSize, QUrl
|
from PySide6.QtCore import Qt, QSize, QUrl
|
||||||
from PySide6.QtGui import QDesktopServices, QColor
|
from PySide6.QtGui import QDesktopServices, QColor
|
||||||
from qfluentwidgets import FluentIcon, ScrollArea, SimpleCardWidget
|
from qfluentwidgets import FluentIcon, ScrollArea, SimpleCardWidget, PrimaryToolButton
|
||||||
|
import shutil
|
||||||
|
import requests
|
||||||
|
import json
|
||||||
|
import time
|
||||||
|
from datetime import datetime
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
from app.core import Config
|
from app.core import Config, MainInfoBar
|
||||||
from .Widget import Banner, IconButton
|
from .Widget import Banner, IconButton
|
||||||
|
|
||||||
|
|
||||||
@@ -47,12 +54,12 @@ class Home(QWidget):
|
|||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
self.setObjectName("主页")
|
self.setObjectName("主页")
|
||||||
|
|
||||||
widget = Banner(str(Config.app_path / "resources/images/Home.png"))
|
self.banner = Banner()
|
||||||
widget.set_percentage_size(
|
self.banner.set_percentage_size(
|
||||||
0.8, 0.5
|
0.8, 0.5
|
||||||
) # 设置 Banner 大小为窗口的 80% 宽度和 50% 高度
|
) # 设置 Banner 大小为窗口的 80% 宽度和 50% 高度
|
||||||
|
|
||||||
v_layout = QVBoxLayout(widget)
|
v_layout = QVBoxLayout(self.banner)
|
||||||
v_layout.setContentsMargins(0, 0, 0, 15)
|
v_layout.setContentsMargins(0, 0, 0, 15)
|
||||||
v_layout.setSpacing(5)
|
v_layout.setSpacing(5)
|
||||||
v_layout.setAlignment(Qt.AlignmentFlag.AlignTop)
|
v_layout.setAlignment(Qt.AlignmentFlag.AlignTop)
|
||||||
@@ -88,13 +95,216 @@ class Home(QWidget):
|
|||||||
)
|
)
|
||||||
v_layout.addStretch()
|
v_layout.addStretch()
|
||||||
|
|
||||||
|
# 中间留白区域
|
||||||
|
v_layout.addItem(
|
||||||
|
QSpacerItem(10, 10, QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Minimum)
|
||||||
|
)
|
||||||
|
v_layout.addStretch()
|
||||||
|
|
||||||
|
# 底部部分 (图片切换按钮)
|
||||||
|
h2_layout = QHBoxLayout()
|
||||||
|
h2_layout.setAlignment(Qt.AlignmentFlag.AlignTop)
|
||||||
|
|
||||||
|
# 左边留白区域
|
||||||
|
h2_layout.addItem(
|
||||||
|
QSpacerItem(20, 10, QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Minimum)
|
||||||
|
)
|
||||||
|
|
||||||
|
# # 公告卡片
|
||||||
|
# noticeCard = NoticeCard()
|
||||||
|
# h2_layout.addWidget(noticeCard)
|
||||||
|
|
||||||
|
h2_layout.addStretch()
|
||||||
|
|
||||||
|
# 自定义图像按钮布局
|
||||||
|
self.imageButton = PrimaryToolButton(FluentIcon.IMAGE_EXPORT)
|
||||||
|
self.imageButton.setFixedSize(56, 56)
|
||||||
|
self.imageButton.setIconSize(QSize(32, 32))
|
||||||
|
self.imageButton.clicked.connect(self.get_home_image)
|
||||||
|
|
||||||
|
v1_layout = QVBoxLayout()
|
||||||
|
v1_layout.addWidget(self.imageButton, alignment=Qt.AlignmentFlag.AlignBottom)
|
||||||
|
|
||||||
|
h2_layout.addLayout(v1_layout)
|
||||||
|
|
||||||
|
# 空白占位符
|
||||||
|
h2_layout.addItem(
|
||||||
|
QSpacerItem(25, 10, QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Minimum)
|
||||||
|
)
|
||||||
|
|
||||||
|
# 将底部水平布局添加到垂直布局
|
||||||
|
v_layout.addLayout(h2_layout)
|
||||||
|
|
||||||
layout = QVBoxLayout()
|
layout = QVBoxLayout()
|
||||||
scrollArea = ScrollArea()
|
scrollArea = ScrollArea()
|
||||||
scrollArea.setWidgetResizable(True)
|
scrollArea.setWidgetResizable(True)
|
||||||
scrollArea.setWidget(widget)
|
scrollArea.setWidget(self.banner)
|
||||||
layout.addWidget(scrollArea)
|
layout.addWidget(scrollArea)
|
||||||
self.setLayout(layout)
|
self.setLayout(layout)
|
||||||
|
|
||||||
|
self.set_banner()
|
||||||
|
|
||||||
|
def get_home_image(self) -> None:
|
||||||
|
"""获取主页图片"""
|
||||||
|
|
||||||
|
if (
|
||||||
|
Config.global_config.get(Config.global_config.function_HomeImageMode)
|
||||||
|
== "默认"
|
||||||
|
):
|
||||||
|
pass
|
||||||
|
elif (
|
||||||
|
Config.global_config.get(Config.global_config.function_HomeImageMode)
|
||||||
|
== "自定义"
|
||||||
|
):
|
||||||
|
|
||||||
|
file_path, _ = QFileDialog.getOpenFileName(
|
||||||
|
self, "打开自定义主页图片", "", "图片文件 (*.png *.jpg *.bmp)"
|
||||||
|
)
|
||||||
|
if file_path:
|
||||||
|
|
||||||
|
for file in Config.app_path.glob(
|
||||||
|
"resources/images/Home/BannerCustomize.*"
|
||||||
|
):
|
||||||
|
file.unlink()
|
||||||
|
|
||||||
|
shutil.copy(
|
||||||
|
file_path,
|
||||||
|
Config.app_path
|
||||||
|
/ f"resources/images/Home/BannerCustomize{Path(file_path).suffix}",
|
||||||
|
)
|
||||||
|
|
||||||
|
logger.info(f"自定义主页图片更换成功:{file_path}")
|
||||||
|
MainInfoBar.push_info_bar(
|
||||||
|
"success",
|
||||||
|
"主页图片更换成功",
|
||||||
|
"自定义主页图片更换成功!",
|
||||||
|
3000,
|
||||||
|
)
|
||||||
|
|
||||||
|
else:
|
||||||
|
logger.warning("自定义主页图片更换失败:未选择图片文件")
|
||||||
|
MainInfoBar.push_info_bar(
|
||||||
|
"warning",
|
||||||
|
"主页图片更换失败",
|
||||||
|
"未选择图片文件!",
|
||||||
|
5000,
|
||||||
|
)
|
||||||
|
elif (
|
||||||
|
Config.global_config.get(Config.global_config.function_HomeImageMode)
|
||||||
|
== "主题图像"
|
||||||
|
):
|
||||||
|
|
||||||
|
# 从远程服务器获取最新主题图像
|
||||||
|
for _ in range(3):
|
||||||
|
try:
|
||||||
|
response = requests.get(
|
||||||
|
"https://gitee.com/DLmaster_361/AUTO_MAA/raw/server/theme_image.json"
|
||||||
|
)
|
||||||
|
theme_image = response.json()
|
||||||
|
break
|
||||||
|
except Exception as e:
|
||||||
|
err = e
|
||||||
|
time.sleep(0.1)
|
||||||
|
else:
|
||||||
|
logger.error(f"获取最新主题图像时出错:\n{err}")
|
||||||
|
MainInfoBar.push_info_bar(
|
||||||
|
"error",
|
||||||
|
"主题图像获取失败",
|
||||||
|
f"获取最新主题图像信息时出错:\n{err}",
|
||||||
|
-1,
|
||||||
|
)
|
||||||
|
return None
|
||||||
|
|
||||||
|
if (Config.app_path / "resources/theme_image.json").exists():
|
||||||
|
with (Config.app_path / "resources/theme_image.json").open(
|
||||||
|
mode="r", encoding="utf-8"
|
||||||
|
) as f:
|
||||||
|
theme_image_local = json.load(f)
|
||||||
|
time_local = datetime.strptime(
|
||||||
|
theme_image_local["time"], "%Y-%m-%d %H:%M"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
time_local = datetime.strptime("2000-01-01 00:00", "%Y-%m-%d %H:%M")
|
||||||
|
|
||||||
|
if not (
|
||||||
|
Config.app_path / "resources/images/Home/BannerTheme.jpg"
|
||||||
|
).exists() or (
|
||||||
|
datetime.now()
|
||||||
|
> datetime.strptime(theme_image["time"], "%Y-%m-%d %H:%M")
|
||||||
|
and datetime.strptime(theme_image["time"], "%Y-%m-%d %H:%M")
|
||||||
|
> time_local
|
||||||
|
):
|
||||||
|
|
||||||
|
response = requests.get(theme_image["url"])
|
||||||
|
if response.status_code == 200:
|
||||||
|
|
||||||
|
with open(
|
||||||
|
Config.app_path / "resources/images/Home/BannerTheme.jpg", "wb"
|
||||||
|
) as file:
|
||||||
|
file.write(response.content)
|
||||||
|
|
||||||
|
logger.info("主题图像下载成功")
|
||||||
|
MainInfoBar.push_info_bar(
|
||||||
|
"success",
|
||||||
|
"主题图像下载成功",
|
||||||
|
"主题图像下载成功!",
|
||||||
|
3000,
|
||||||
|
)
|
||||||
|
|
||||||
|
else:
|
||||||
|
|
||||||
|
logger.error("主题图像下载失败")
|
||||||
|
MainInfoBar.push_info_bar(
|
||||||
|
"error",
|
||||||
|
"主题图像下载失败",
|
||||||
|
f"主题图像下载失败:{response.status_code}",
|
||||||
|
-1,
|
||||||
|
)
|
||||||
|
|
||||||
|
with (Config.app_path / "resources/theme_image.json").open(
|
||||||
|
mode="w", encoding="utf-8"
|
||||||
|
) as f:
|
||||||
|
json.dump(theme_image, f, ensure_ascii=False, indent=4)
|
||||||
|
|
||||||
|
else:
|
||||||
|
|
||||||
|
logger.info("主题图像已是最新")
|
||||||
|
MainInfoBar.push_info_bar(
|
||||||
|
"info",
|
||||||
|
"主题图像已是最新",
|
||||||
|
"主题图像已是最新!",
|
||||||
|
3000,
|
||||||
|
)
|
||||||
|
|
||||||
|
self.set_banner()
|
||||||
|
|
||||||
|
def set_banner(self):
|
||||||
|
"""设置主页图像"""
|
||||||
|
if (
|
||||||
|
Config.global_config.get(Config.global_config.function_HomeImageMode)
|
||||||
|
== "默认"
|
||||||
|
):
|
||||||
|
self.banner.set_banner_image(
|
||||||
|
str(Config.app_path / "resources/images/Home/BannerDefault.png")
|
||||||
|
)
|
||||||
|
self.imageButton.hide()
|
||||||
|
elif (
|
||||||
|
Config.global_config.get(Config.global_config.function_HomeImageMode)
|
||||||
|
== "自定义"
|
||||||
|
):
|
||||||
|
for file in Config.app_path.glob("resources/images/Home/BannerCustomize.*"):
|
||||||
|
self.banner.set_banner_image(str(file))
|
||||||
|
break
|
||||||
|
self.imageButton.show()
|
||||||
|
elif (
|
||||||
|
Config.global_config.get(Config.global_config.function_HomeImageMode)
|
||||||
|
== "主题图像"
|
||||||
|
):
|
||||||
|
self.banner.set_banner_image(
|
||||||
|
str(Config.app_path / "resources/images/Home/BannerTheme.jpg")
|
||||||
|
)
|
||||||
|
self.imageButton.show()
|
||||||
|
|
||||||
|
|
||||||
class ButtonGroup(SimpleCardWidget):
|
class ButtonGroup(SimpleCardWidget):
|
||||||
"""显示主页和 GitHub 按钮的竖直按钮组"""
|
"""显示主页和 GitHub 按钮的竖直按钮组"""
|
||||||
|
|||||||
@@ -193,6 +193,11 @@ class AUTO_MAA(MSFluentWindow):
|
|||||||
lambda: self.show_ui("配置托盘")
|
lambda: self.show_ui("配置托盘")
|
||||||
)
|
)
|
||||||
self.setting.ui.card_IfToTray.checkedChanged.connect(self.set_min_method)
|
self.setting.ui.card_IfToTray.checkedChanged.connect(self.set_min_method)
|
||||||
|
self.setting.function.card_HomeImageMode.comboBox.currentIndexChanged.connect(
|
||||||
|
lambda index: (
|
||||||
|
self.home.get_home_image() if index == 2 else self.home.set_banner()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
self.splashScreen.finish()
|
self.splashScreen.finish()
|
||||||
|
|
||||||
@@ -229,6 +234,12 @@ class AUTO_MAA(MSFluentWindow):
|
|||||||
# 获取公告
|
# 获取公告
|
||||||
self.setting.show_notice(if_show=False)
|
self.setting.show_notice(if_show=False)
|
||||||
|
|
||||||
|
if (
|
||||||
|
Config.global_config.get(Config.global_config.function_HomeImageMode)
|
||||||
|
== "主题图像"
|
||||||
|
):
|
||||||
|
self.home.get_home_image()
|
||||||
|
|
||||||
# 检查更新
|
# 检查更新
|
||||||
if Config.global_config.get(Config.global_config.update_IfAutoUpdate):
|
if Config.global_config.get(Config.global_config.update_IfAutoUpdate):
|
||||||
result = self.setting.get_update_info()
|
result = self.setting.get_update_info()
|
||||||
|
|||||||
@@ -409,6 +409,13 @@ class FunctionSettingCard(HeaderCardWidget):
|
|||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
self.setTitle("功能")
|
self.setTitle("功能")
|
||||||
|
|
||||||
|
self.card_HomeImageMode = ComboBoxSettingCard(
|
||||||
|
configItem=Config.global_config.function_HomeImageMode,
|
||||||
|
icon=FluentIcon.PAGE_RIGHT,
|
||||||
|
title="主页背景图模式",
|
||||||
|
content="选择主页背景图的来源",
|
||||||
|
texts=["默认", "自定义", "主题图像"],
|
||||||
|
)
|
||||||
self.card_HistoryRetentionTime = ComboBoxSettingCard(
|
self.card_HistoryRetentionTime = ComboBoxSettingCard(
|
||||||
configItem=Config.global_config.function_HistoryRetentionTime,
|
configItem=Config.global_config.function_HistoryRetentionTime,
|
||||||
icon=FluentIcon.PAGE_RIGHT,
|
icon=FluentIcon.PAGE_RIGHT,
|
||||||
@@ -431,6 +438,7 @@ class FunctionSettingCard(HeaderCardWidget):
|
|||||||
)
|
)
|
||||||
|
|
||||||
Layout = QVBoxLayout()
|
Layout = QVBoxLayout()
|
||||||
|
Layout.addWidget(self.card_HomeImageMode)
|
||||||
Layout.addWidget(self.card_HistoryRetentionTime)
|
Layout.addWidget(self.card_HistoryRetentionTime)
|
||||||
Layout.addWidget(self.card_IfAllowSleep)
|
Layout.addWidget(self.card_IfAllowSleep)
|
||||||
Layout.addWidget(self.card_IfSilence)
|
Layout.addWidget(self.card_IfSilence)
|
||||||
|
|||||||
BIN
resources/images/Home/BannerDefault.png
Normal file
BIN
resources/images/Home/BannerDefault.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.8 MiB |
Reference in New Issue
Block a user