设置界面与实例管理界面初步重构

This commit is contained in:
DLmaster
2025-01-04 04:02:20 +08:00
parent f54e83673f
commit f135a6510f
12 changed files with 1879 additions and 677 deletions

527
app/ui/member_manager.py Normal file
View File

@@ -0,0 +1,527 @@
# <AUTO_MAA:A MAA Multi Account Management and Automation Tool>
# Copyright © <2024> <DLmaster361>
# This file is part of AUTO_MAA.
# AUTO_MAA is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published
# by the Free Software Foundation, either version 3 of the License,
# or (at your option) any later version.
# AUTO_MAA is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty
# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
# the GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with AUTO_MAA. If not, see <https://www.gnu.org/licenses/>.
# DLmaster_361@163.com
"""
AUTO_MAA
AUTO_MAA设置界面
v4.2
作者DLmaster_361
"""
from PySide6.QtWidgets import (
QWidget, #
QMainWindow, #
QApplication, #
QSystemTrayIcon, #
QFileDialog, #
QTabWidget, #
QToolBox, #
QComboBox, #
QTableWidgetItem, #
QHeaderView, #
QVBoxLayout,
QStackedWidget,
QHBoxLayout,
)
from qfluentwidgets import (
Action,
PushButton,
LineEdit,
PasswordLineEdit,
qconfig,
TableWidget,
Pivot,
TimePicker,
ComboBox,
CheckBox,
ScrollArea,
SpinBox,
FluentIcon,
SwitchButton,
RoundMenu,
MessageBox,
MessageBoxBase,
HeaderCardWidget,
BodyLabel,
CommandBar,
SubtitleLabel,
GroupHeaderCardWidget,
SwitchSettingCard,
ExpandGroupSettingCard,
SingleDirectionScrollArea,
PushSettingCard,
)
from PySide6.QtUiTools import QUiLoader
from PySide6.QtGui import QIcon, QCloseEvent
from PySide6 import QtCore
from functools import partial
from typing import List, Tuple
from pathlib import Path
import os
import datetime
import ctypes
import subprocess
import shutil
import win32gui
import win32process
import psutil
import pyautogui
import time
import winreg
import requests
uiLoader = QUiLoader()
from app import AppConfig, MaaConfig
from app.services import Notification, CryptoHandler
from app.utils import Updater, version_text
from .Widget import InputMessageBox, LineEditSettingCard, SpinBoxSettingCard
class MemberManager(QWidget):
def __init__(self, config: AppConfig, notify: Notification, crypto: CryptoHandler):
super(MemberManager, self).__init__()
self.setObjectName("脚本管理")
self.config = config
self.notify = notify
self.crypto = crypto
layout = QVBoxLayout(self)
self.tools = CommandBar()
self.member_manager = MemberSettingBox(self.config)
# 逐个添加动作
self.tools.addActions(
[
Action(
FluentIcon.ADD_TO, "新建脚本实例", triggered=self.add_setting_box
),
Action(
FluentIcon.REMOVE_FROM,
"删除脚本实例",
triggered=self.del_setting_box,
),
]
)
self.tools.addSeparator()
self.tools.addActions(
[
Action(
FluentIcon.LEFT_ARROW, "向左移动", triggered=self.left_setting_box
),
Action(
FluentIcon.RIGHT_ARROW,
"向右移动",
triggered=self.right_setting_box,
),
]
)
# 批量添加动作
self.tools.addAction(
Action(
FluentIcon.HIDE,
"显示/隐藏密码",
checkable=True,
triggered=self.show_password,
),
)
layout.addWidget(self.tools)
layout.addWidget(self.member_manager)
def add_setting_box(self):
"""添加一个脚本实例"""
choice = InputMessageBox(
self, "选择一个脚本类型并添加相应脚本实例", "选择脚本类型", "选择", ["MAA"]
)
if choice.exec() and choice.input.currentIndex() != -1:
if choice.input.currentText() == "MAA":
index = len(self.member_manager.search_member()) + 1
qconfig.load(
self.config.app_path / f"config/MaaConfig/脚本_{index}/config.json",
self.config.maa_config,
)
self.config.maa_config.set(self.config.maa_config.MaaSet_Name, "")
self.config.maa_config.set(self.config.maa_config.MaaSet_Path, ".")
self.config.maa_config.set(
self.config.maa_config.RunSet_AnnihilationTimeLimit, 40
)
self.config.maa_config.set(
self.config.maa_config.RunSet_RoutineTimeLimit, 10
)
self.config.maa_config.set(
self.config.maa_config.RunSet_RunTimesLimit, 3
)
self.config.maa_config.set(self.config.maa_config.MaaSet_Name, "")
self.config.maa_config.set(self.config.maa_config.MaaSet_Name, "")
self.config.maa_config.set(self.config.maa_config.MaaSet_Name, "")
self.config.maa_config.save()
self.member_manager.add_MaaSettingBox(index)
self.member_manager.switch_SettingBox(index)
def del_setting_box(self):
"""删除一个脚本实例"""
name = self.member_manager.pivot.currentRouteKey()
if name == None:
return None
choice = MessageBox(
"确认",
f"确定要删除 {name} 实例吗?",
self,
)
if choice.exec():
member_list = self.member_manager.search_member()
move_list = [_ for _ in member_list if int(_[0][3:]) > int(name[3:])]
type = [_[1] for _ in member_list if _[0] == name]
index = max(int(name[3:]) - 1, 1)
shutil.rmtree(self.config.app_path / f"config/{type[0]}Config/{name}")
for member in move_list:
if (
self.config.app_path / f"config/{member[1]}Config/{member[0]}"
).exists():
(
self.config.app_path / f"config/{member[1]}Config/{member[0]}"
).rename(
self.config.app_path
/ f"config/{member[1]}Config/{member[0][:3]}{int(member[0][3:])-1}",
)
self.member_manager.clear_SettingBox()
self.member_manager.show_SettingBox()
self.member_manager.switch_SettingBox(index, if_after_clear=True)
def left_setting_box(self):
"""向左移动脚本实例"""
name = self.member_manager.pivot.currentRouteKey()
if name == None:
return None
member_list = self.member_manager.search_member()
index = int(name[3:])
if index == 1:
return None
type_right = [_[1] for _ in member_list if _[0] == name]
type_left = [_[1] for _ in member_list if _[0] == f"脚本_{index-1}"]
(self.config.app_path / f"config/{type_right[0]}Config/脚本_{index}").rename(
self.config.app_path / f"config/{type_right[0]}Config/脚本_0",
)
(self.config.app_path / f"config/{type_left[0]}Config/脚本_{index-1}").rename(
self.config.app_path / f"config/{type_left[0]}Config/脚本_{index}",
)
(self.config.app_path / f"config/{type_right[0]}Config/脚本_0").rename(
self.config.app_path / f"config/{type_right[0]}Config/脚本_{index-1}",
)
self.member_manager.clear_SettingBox()
self.member_manager.show_SettingBox()
self.member_manager.switch_SettingBox(index - 1, if_after_clear=True)
def right_setting_box(self):
"""向左移动脚本实例"""
name = self.member_manager.pivot.currentRouteKey()
if name == None:
return None
member_list = self.member_manager.search_member()
index = int(name[3:])
if index == len(member_list):
return None
type_left = [_[1] for _ in member_list if _[0] == name]
type_right = [_[1] for _ in member_list if _[0] == f"脚本_{index+1}"]
(self.config.app_path / f"config/{type_left[0]}Config/脚本_{index}").rename(
self.config.app_path / f"config/{type_left[0]}Config/脚本_0",
)
(self.config.app_path / f"config/{type_right[0]}Config/脚本_{index+1}").rename(
self.config.app_path / f"config/{type_right[0]}Config/脚本_{index}",
)
(self.config.app_path / f"config/{type_left[0]}Config/脚本_0").rename(
self.config.app_path / f"config/{type_left[0]}Config/脚本_{index+1}",
)
self.member_manager.clear_SettingBox()
self.member_manager.show_SettingBox()
self.member_manager.switch_SettingBox(index + 1, if_after_clear=True)
def show_password(self):
pass
class MemberSettingBox(QWidget):
def __init__(self, config: AppConfig):
super().__init__()
self.setObjectName("脚本管理")
self.config = config
self.pivot = Pivot(self)
self.stackedWidget = QStackedWidget(self)
self.Layout = QVBoxLayout(self)
self.SubInterface: List[MaaSettingBox] = []
self.Layout.addWidget(self.pivot, 0, QtCore.Qt.AlignHCenter)
self.Layout.addWidget(self.stackedWidget)
self.Layout.setContentsMargins(0, 0, 0, 0)
self.pivot.currentItemChanged.connect(
lambda index: self.stackedWidget.setCurrentWidget(
self.findChild(QWidget, index)
)
)
self.pivot.currentItemChanged.connect(
lambda index: qconfig.load(
self.config.app_path / f"config/MaaConfig/{index}/config.json",
self.config.maa_config,
)
)
self.show_SettingBox()
self.switch_SettingBox(1)
def show_SettingBox(self) -> None:
"""加载所有子界面"""
member_list = self.search_member()
for member in member_list:
if member[1] == "Maa":
self.add_MaaSettingBox(int(member[0][3:]))
def switch_SettingBox(self, index: int, if_after_clear: bool = False) -> None:
"""切换到指定的子界面"""
member_list = self.search_member()
if index > len(member_list):
return None
type = [_[1] for _ in member_list if _[0] == f"脚本_{index}"]
if if_after_clear:
self.pivot.currentItemChanged.disconnect()
self.stackedWidget.setCurrentWidget(self.SubInterface[index - 1])
self.pivot.setCurrentItem(self.SubInterface[index - 1].objectName())
qconfig.load(
self.config.app_path
/ f"config/{type[0]}Config/{self.SubInterface[index-1].objectName()}/config.json",
self.config.maa_config,
)
if if_after_clear:
self.pivot.currentItemChanged.connect(
lambda index: self.stackedWidget.setCurrentWidget(
self.findChild(QWidget, index)
)
)
self.pivot.currentItemChanged.connect(
lambda index: qconfig.load(
self.config.app_path / f"config/MaaConfig/{index}/config.json",
self.config.maa_config,
)
)
def clear_SettingBox(self) -> None:
"""清空所有子界面"""
for sub_interface in self.SubInterface:
self.stackedWidget.removeWidget(sub_interface)
sub_interface.deleteLater()
self.SubInterface.clear()
self.pivot.clear()
def add_MaaSettingBox(self, uid: int) -> None:
"""添加一个MAA设置界面"""
maa_setting_box = MaaSettingBox(self.config, uid)
self.SubInterface.append(maa_setting_box)
self.stackedWidget.addWidget(self.SubInterface[-1])
self.pivot.addItem(routeKey=f"脚本_{uid}", text=f"脚本 {uid}")
def search_member(self) -> list:
"""搜索所有脚本实例"""
member_list = []
if (self.config.app_path / "config/MaaConfig").exists():
for subdir in (self.config.app_path / "config/MaaConfig").iterdir():
if subdir.is_dir():
member_list.append([subdir.name, "Maa"])
return member_list
class MaaSettingBox(QWidget):
def __init__(self, config: AppConfig, uid: int):
super().__init__()
self.setObjectName(f"脚本_{uid}")
self.config = config
layout = QVBoxLayout()
scrollArea = ScrollArea()
scrollArea.setWidgetResizable(True)
content_widget = QWidget()
content_layout = QVBoxLayout(content_widget)
self.app_setting = self.AppSettingCard(self, self.config.maa_config)
content_layout.addWidget(self.app_setting)
content_layout.addStretch(1)
scrollArea.setWidget(content_widget)
layout.addWidget(scrollArea)
self.setLayout(layout)
class AppSettingCard(HeaderCardWidget):
def __init__(self, parent=None, maa_config: MaaConfig = None):
super().__init__(parent)
self.setTitle("MAA实例")
self.maa_config = maa_config
Layout = QVBoxLayout()
self.card_Name = LineEditSettingCard(
"实例名称",
FluentIcon.EDIT,
"实例名称",
"用于标识MAA实例的名称",
self.maa_config.MaaSet_Name,
)
self.card_Path = PushSettingCard(
"选择文件夹",
FluentIcon.FOLDER,
"MAA目录",
self.maa_config.get(self.maa_config.MaaSet_Path),
)
self.card_Set = PushSettingCard(
"设置",
FluentIcon.HOME,
"MAA全局配置",
"简洁模式下MAA将继承全局配置",
)
self.RunSet = self.RunSetSettingCard(self, self.maa_config)
self.card_Path.clicked.connect(self.PathClicked)
Layout.addWidget(self.card_Name)
Layout.addWidget(self.card_Path)
Layout.addWidget(self.card_Set)
Layout.addWidget(self.RunSet)
self.viewLayout.addLayout(Layout)
def PathClicked(self):
folder = QFileDialog.getExistingDirectory(self, "选择MAA目录", "./")
if not folder or self.maa_config.get(self.maa_config.MaaSet_Path) == folder:
return
self.maa_config.set(self.maa_config.MaaSet_Path, folder)
self.card_Path.setContent(folder)
class RunSetSettingCard(ExpandGroupSettingCard):
def __init__(self, parent=None, maa_config: MaaConfig = None):
super().__init__(
FluentIcon.SETTING,
"运行",
"MAA运行调控选项",
parent,
)
self.maa_config = maa_config
widget = QWidget()
Layout = QVBoxLayout(widget)
self.AnnihilationTimeLimit = SpinBoxSettingCard(
(1, 1024),
FluentIcon.PAGE_RIGHT,
"剿灭代理超时限制",
"MAA日志无变化时间超过该阈值视为超时",
self.maa_config.RunSet_AnnihilationTimeLimit,
)
self.RoutineTimeLimit = SpinBoxSettingCard(
(1, 1024),
FluentIcon.PAGE_RIGHT,
"日常代理超时限制",
"MAA日志无变化时间超过该阈值视为超时",
self.maa_config.RunSet_RoutineTimeLimit,
)
self.RunTimesLimit = SpinBoxSettingCard(
(1, 1024),
FluentIcon.PAGE_RIGHT,
"代理重试次数限制",
"若超过该次数限制仍未完成代理,视为代理失败",
self.maa_config.RunSet_RunTimesLimit,
)
Layout.addWidget(self.AnnihilationTimeLimit)
Layout.addWidget(self.RoutineTimeLimit)
Layout.addWidget(self.RunTimesLimit)
self.viewLayout.setContentsMargins(0, 0, 0, 0)
self.viewLayout.setSpacing(0)
self.addGroupWidget(widget)