设置界面与实例管理界面初步重构
This commit is contained in:
527
app/ui/member_manager.py
Normal file
527
app/ui/member_manager.py
Normal 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)
|
||||
Reference in New Issue
Block a user