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

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

View File

@@ -29,7 +29,7 @@ __version__ = "4.2.0"
__author__ = "DLmaster361 <DLmaster_361@163.com>"
__license__ = "GPL-3.0 license"
from .config import AppConfig
from .config import AppConfig, MaaConfig
from .models import MaaManager
from .services import Notification, CryptoHandler
from .ui import AUTO_MAA
@@ -37,6 +37,7 @@ from .utils import Updater, version_text
__all__ = [
"AppConfig",
"MaaConfig",
"MaaManager",
"Notification",
"CryptoHandler",

View File

@@ -31,6 +31,18 @@ import os
import sys
from pathlib import Path
from typing import Dict, Union
from qfluentwidgets import (
QConfig,
ConfigItem,
qconfig,
OptionsConfigItem,
RangeConfigItem,
OptionsValidator,
FolderValidator,
BoolValidator,
RangeValidator,
EnumSerializer,
)
class AppConfig:
@@ -42,7 +54,7 @@ class AppConfig:
self.app_name = os.path.basename(self.app_path) # 获取软件自身的名称
self.database_path = self.app_path / "data/data.db"
self.config_path = self.app_path / "config/gui.json"
self.config_path = self.app_path / "config/config.json"
self.key_path = self.app_path / "data/key"
self.gameid_path = self.app_path / "data/gameid.txt"
self.version_path = self.app_path / "resources/version.json"
@@ -68,12 +80,6 @@ class AppConfig:
with self.version_path.open(mode="w", encoding="utf-8") as f:
json.dump(version, f, indent=4)
# 生成配置文件
if not self.config_path.exists():
config = {"Default": {}}
with self.config_path.open(mode="w", encoding="utf-8") as f:
json.dump(config, f, indent=4)
# 生成预设gameid替换方案文件
if not self.gameid_path.exists():
self.gameid_path.write_text(
@@ -87,60 +93,11 @@ class AppConfig:
def check_config(self) -> None:
"""检查配置文件字段完整性并补全"""
config_list = [
["TimeSet.set1", "False"],
["TimeSet.run1", "00:00"],
["TimeSet.set2", "False"],
["TimeSet.run2", "00:00"],
["TimeSet.set3", "False"],
["TimeSet.run3", "00:00"],
["TimeSet.set4", "False"],
["TimeSet.run4", "00:00"],
["TimeSet.set5", "False"],
["TimeSet.run5", "00:00"],
["TimeSet.set6", "False"],
["TimeSet.run6", "00:00"],
["TimeSet.set7", "False"],
["TimeSet.run7", "00:00"],
["TimeSet.set8", "False"],
["TimeSet.run8", "00:00"],
["TimeSet.set9", "False"],
["TimeSet.run9", "00:00"],
["TimeSet.set10", "False"],
["TimeSet.run10", "00:00"],
["MaaSet.path", ""],
["TimeLimit.routine", 10],
["TimeLimit.annihilation", 40],
["TimesLimit.run", 3],
["SelfSet.IfSelfStart", "False"],
["SelfSet.IfSleep", "False"],
["SelfSet.IfProxyDirectly", "False"],
["SelfSet.IfSendMail", "False"],
["SelfSet.MailAddress", ""],
["SelfSet.IfSendMail.OnlyError", "False"],
["SelfSet.IfSilence", "False"],
["SelfSet.BossKey", ""],
["SelfSet.IfToTray", "False"],
["SelfSet.UIsize", "1200x700"],
["SelfSet.UIlocation", "100x100"],
["SelfSet.UImaximized", "False"],
["SelfSet.MainIndex", 2],
]
self.global_config = GlobalConfig()
qconfig.load(self.config_path, self.global_config)
self.global_config.save()
# 导入配置文件
with self.config_path.open(mode="r", encoding="utf-8") as f:
config = json.load(f)
# 检查并补充缺失的字段
for i in range(len(config_list)):
if not config_list[i][0] in config["Default"]:
config["Default"][config_list[i][0]] = config_list[i][1]
# 初始化配置信息
self.content: Dict[str, Dict[str, Union[str, int]]] = config
# 导出配置文件
self.save_config()
self.maa_config = MaaConfig()
def check_database(self) -> None:
"""检查用户数据库文件并处理数据库版本更新"""
@@ -233,8 +190,71 @@ class AppConfig:
self.cur.close()
self.db.close()
def save_config(self) -> None:
"""保存配置文件"""
with self.config_path.open(mode="w", encoding="utf-8") as f:
json.dump(self.content, f, indent=4)
class GlobalConfig(QConfig):
"""全局配置"""
# ["TimeSet.set1", "False"],
# ["TimeSet.run1", "00:00"],
# ["TimeSet.set2", "False"],
# ["TimeSet.run2", "00:00"],
# ["TimeSet.set3", "False"],
# ["TimeSet.run3", "00:00"],
# ["TimeSet.set4", "False"],
# ["TimeSet.run4", "00:00"],
# ["TimeSet.set5", "False"],
# ["TimeSet.run5", "00:00"],
# ["TimeSet.set6", "False"],
# ["TimeSet.run6", "00:00"],
# ["TimeSet.set7", "False"],
# ["TimeSet.run7", "00:00"],
# ["TimeSet.set8", "False"],
# ["TimeSet.run8", "00:00"],
# ["TimeSet.set9", "False"],
# ["TimeSet.run9", "00:00"],
# ["TimeSet.set10", "False"],
# ["TimeSet.run10", "00:00"],
# ["MaaSet.path", ""],
# ["TimeLimit.routine", 10],
# ["TimeLimit.annihilation", 40],
# ["TimesLimit.run", 3],
function_IfSleep = ConfigItem("Function", "IfSleep", False, BoolValidator())
function_IfSilence = ConfigItem("Function", "IfSilence", False, BoolValidator())
function_BossKey = ConfigItem("Function", "BossKey", "")
start_IfSelfStart = ConfigItem("Start", "IfSelfStart", False, BoolValidator())
start_IfRunDirectly = ConfigItem("Start", "IfRunDirectly", False, BoolValidator())
ui_IfShowTray = ConfigItem("UI", "IfShowTray", False, BoolValidator())
ui_IfToTray = ConfigItem("UI", "IfToTray", False, BoolValidator())
ui_size = ConfigItem("UI", "size", "1200x700")
ui_location = ConfigItem("UI", "location", "100x100")
ui_maximized = ConfigItem("UI", "maximized", False, BoolValidator())
ui_MainIndex = RangeConfigItem("UI", "MainIndex", 0, RangeValidator(0, 3))
notify_IfPushPlyer = ConfigItem("Notify", "IfPushPlyer", False, BoolValidator())
notify_IfSendMail = ConfigItem("Notify", "IfSendMail", False, BoolValidator())
notify_IfSendErrorOnly = ConfigItem(
"Notify", "IfSendErrorOnly", False, BoolValidator()
)
notify_MailAddress = ConfigItem("Notify", "MailAddress", "")
update_IfAutoUpdate = ConfigItem("Update", "IfAutoUpdate", False, BoolValidator())
class MaaConfig(QConfig):
"""MAA配置"""
MaaSet_Name = ConfigItem("MaaSet", "Name", "")
MaaSet_Path = ConfigItem("MaaSet", "Path", ".", FolderValidator())
RunSet_AnnihilationTimeLimit = RangeConfigItem(
"RunSet", "AnnihilationTimeLimit", 40, RangeValidator(1, 1024)
)
RunSet_RoutineTimeLimit = RangeConfigItem(
"RunSet", "RoutineTimeLimit", 10, RangeValidator(1, 1024)
)
RunSet_RunTimesLimit = RangeConfigItem(
"RunSet", "RunTimesLimit", 3, RangeValidator(1, 1024)
)

View File

@@ -33,6 +33,18 @@ import subprocess
import shutil
import time
from pathlib import Path
from qfluentwidgets import (
QConfig,
ConfigItem,
qconfig,
OptionsConfigItem,
RangeConfigItem,
OptionsValidator,
BoolValidator,
RangeValidator,
EnumSerializer,
FolderValidator,
)
from app import AppConfig

149
app/ui/Widget.py Normal file
View File

@@ -0,0 +1,149 @@
# <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.QtCore import Qt
from PySide6.QtGui import QIcon
from qfluentwidgets import (
LineEdit,
PasswordLineEdit,
MessageBoxBase,
SubtitleLabel,
SettingCard,
SpinBox,
FluentIconBase,
Signal,
ComboBox,
qconfig,
ConfigItem,
)
from typing import Union
class InputMessageBox(MessageBoxBase):
"""输入对话框"""
def __init__(self, parent, title: str, content: str, mode: str, list: list = None):
super().__init__(parent)
self.title = SubtitleLabel(title)
if mode == "明文":
self.input = LineEdit()
self.input.setClearButtonEnabled(True)
elif mode == "密码":
self.input = PasswordLineEdit()
elif mode == "选择":
self.input = ComboBox()
self.input.addItems(list)
self.input.setCurrentIndex(-1)
self.input.setPlaceholderText(content)
# 将组件添加到布局中
self.viewLayout.addWidget(self.title)
self.viewLayout.addWidget(self.input)
class LineEditSettingCard(SettingCard):
"""Setting card with switch button"""
textChanged = Signal(str)
def __init__(
self,
text,
icon: Union[str, QIcon, FluentIconBase],
title,
content=None,
configItem: ConfigItem = None,
parent=None,
):
super().__init__(icon, title, content, parent)
self.configItem = configItem
self.LineEdit = LineEdit(self)
self.LineEdit.setMinimumWidth(250)
self.LineEdit.setPlaceholderText(text)
if configItem:
self.setValue(qconfig.get(configItem))
configItem.valueChanged.connect(self.setValue)
self.hBoxLayout.addWidget(self.LineEdit, 0, Qt.AlignRight)
self.hBoxLayout.addSpacing(16)
self.LineEdit.textChanged.connect(self.__textChanged)
def __textChanged(self, content: str):
self.setValue(content)
self.textChanged.emit(content)
def setValue(self, content: str):
if self.configItem:
qconfig.set(self.configItem, content)
self.LineEdit.setText(content)
class SpinBoxSettingCard(SettingCard):
textChanged = Signal(int)
def __init__(
self,
range: tuple[int, int],
icon: Union[str, QIcon, FluentIconBase],
title,
content=None,
configItem: ConfigItem = None,
parent=None,
):
super().__init__(icon, title, content, parent)
self.configItem = configItem
self.SpinBox = SpinBox(self)
self.SpinBox.setRange(range[0], range[1])
self.SpinBox.setMinimumWidth(150)
if configItem:
self.setValue(qconfig.get(configItem))
configItem.valueChanged.connect(self.setValue)
self.hBoxLayout.addWidget(self.SpinBox, 0, Qt.AlignRight)
self.hBoxLayout.addSpacing(16)
self.SpinBox.valueChanged.connect(self.__valueChanged)
def __valueChanged(self, value: int):
self.setValue(value)
self.textChanged.emit(value)
def setValue(self, value: int):
if self.configItem:
qconfig.set(self.configItem, value)
self.SpinBox.setValue(value)

View File

@@ -29,6 +29,6 @@ __version__ = "4.2.0"
__author__ = "DLmaster361 <DLmaster_361@163.com>"
__license__ = "GPL-3.0 license"
from .gui import AUTO_MAA
from .main_window import AUTO_MAA
__all__ = ["AUTO_MAA"]

View File

@@ -1,88 +1,3 @@
# <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, #
)
from qfluentwidgets import (
Action,
PushButton,
LineEdit,
PasswordLineEdit,
TextBrowser,
TableWidget,
TimePicker,
ComboBox,
CheckBox,
SpinBox,
FluentIcon,
RoundMenu,
MessageBox,
MessageBoxBase,
HeaderCardWidget,
BodyLabel,
SubtitleLabel,
)
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 json
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
from app.models import MaaManager
from app.services import Notification, CryptoHandler
from app.utils import Updater, version_text
class Main(QWidget):
ES_CONTINUOUS = 0x80000000
@@ -158,168 +73,168 @@ class Main(QWidget):
"-",
]
uiLoader.registerCustomWidget(PushButton)
uiLoader.registerCustomWidget(LineEdit)
uiLoader.registerCustomWidget(TextBrowser)
uiLoader.registerCustomWidget(TableWidget)
uiLoader.registerCustomWidget(TimePicker)
uiLoader.registerCustomWidget(SpinBox)
uiLoader.registerCustomWidget(CheckBox)
uiLoader.registerCustomWidget(HeaderCardWidget)
uiLoader.registerCustomWidget(BodyLabel)
# uiLoader.registerCustomWidget(PushButton)
# uiLoader.registerCustomWidget(LineEdit)
# uiLoader.registerCustomWidget(TextBrowser)
# uiLoader.registerCustomWidget(TableWidget)
# uiLoader.registerCustomWidget(TimePicker)
# uiLoader.registerCustomWidget(SpinBox)
# uiLoader.registerCustomWidget(CheckBox)
# uiLoader.registerCustomWidget(HeaderCardWidget)
# uiLoader.registerCustomWidget(BodyLabel)
# 导入ui配置
self.ui = uiLoader.load(self.config.app_path / "resources/gui/main.ui")
self.ui.setWindowIcon(
QIcon(str(self.config.app_path / "resources/icons/AUTO_MAA.ico"))
)
# # 导入ui配置
# self.ui = uiLoader.load(self.config.app_path / "resources/gui/main.ui")
# self.ui.setWindowIcon(
# QIcon(str(self.config.app_path / "resources/icons/AUTO_MAA.ico"))
# )
# 初始化控件
self.main_tab: QTabWidget = self.ui.findChild(QTabWidget, "tabWidget_main")
self.main_tab.currentChanged.connect(self.change_config)
# # 初始化控件
# self.main_tab: QTabWidget = self.ui.findChild(QTabWidget, "tabWidget_main")
# self.main_tab.currentChanged.connect(self.change_config)
self.user_set: QToolBox = self.ui.findChild(QToolBox, "toolBox_userset")
self.user_set.currentChanged.connect(lambda: self.update_user_info("normal"))
# self.user_set: QToolBox = self.ui.findChild(QToolBox, "toolBox_userset")
# self.user_set.currentChanged.connect(lambda: self.update_user_info("normal"))
self.user_list_simple: TableWidget = self.ui.findChild(
TableWidget, "tableWidget_userlist_simple"
)
self.user_list_simple.itemChanged.connect(
lambda item: self.change_user_Item(item, "simple")
)
# self.user_list_simple: TableWidget = self.ui.findChild(
# TableWidget, "tableWidget_userlist_simple"
# )
# self.user_list_simple.itemChanged.connect(
# lambda item: self.change_user_Item(item, "simple")
# )
self.user_list_beta: TableWidget = self.ui.findChild(
TableWidget, "tableWidget_userlist_beta"
)
self.user_list_beta.itemChanged.connect(
lambda item: self.change_user_Item(item, "beta")
)
# self.user_list_beta: TableWidget = self.ui.findChild(
# TableWidget, "tableWidget_userlist_beta"
# )
# self.user_list_beta.itemChanged.connect(
# lambda item: self.change_user_Item(item, "beta")
# )
self.user_add: PushButton = self.ui.findChild(PushButton, "pushButton_new")
self.user_add.setIcon(FluentIcon.ADD_TO)
self.user_add.clicked.connect(self.add_user)
# self.user_add: PushButton = self.ui.findChild(PushButton, "pushButton_new")
# self.user_add.setIcon(FluentIcon.ADD_TO)
# self.user_add.clicked.connect(self.add_user)
self.user_del: PushButton = self.ui.findChild(PushButton, "pushButton_del")
self.user_del.setIcon(FluentIcon.REMOVE_FROM)
self.user_del.clicked.connect(self.del_user)
# self.user_del: PushButton = self.ui.findChild(PushButton, "pushButton_del")
# self.user_del.setIcon(FluentIcon.REMOVE_FROM)
# self.user_del.clicked.connect(self.del_user)
self.user_switch: PushButton = self.ui.findChild(
PushButton, "pushButton_switch"
)
self.user_switch.setIcon(FluentIcon.MOVE)
self.user_switch.clicked.connect(self.switch_user)
# self.user_switch: PushButton = self.ui.findChild(
# PushButton, "pushButton_switch"
# )
# self.user_switch.setIcon(FluentIcon.MOVE)
# self.user_switch.clicked.connect(self.switch_user)
self.read_PASSWORD: PushButton = self.ui.findChild(
PushButton, "pushButton_password"
)
self.read_PASSWORD.setIcon(FluentIcon.HIDE)
self.read_PASSWORD.clicked.connect(lambda: self.read("key"))
# self.read_PASSWORD: PushButton = self.ui.findChild(
# PushButton, "pushButton_password"
# )
# self.read_PASSWORD.setIcon(FluentIcon.HIDE)
# self.read_PASSWORD.clicked.connect(lambda: self.read("key"))
self.refresh: PushButton = self.ui.findChild(PushButton, "pushButton_refresh")
self.refresh.setIcon(FluentIcon.SYNC)
self.refresh.clicked.connect(lambda: self.update_user_info("clear"))
# self.refresh: PushButton = self.ui.findChild(PushButton, "pushButton_refresh")
# self.refresh.setIcon(FluentIcon.SYNC)
# self.refresh.clicked.connect(lambda: self.update_user_info("clear"))
self.run_now: PushButton = self.ui.findChild(PushButton, "pushButton_runnow")
self.run_now.setIcon(FluentIcon.PLAY)
self.run_now.clicked.connect(lambda: self.maa_starter("日常代理"))
# self.run_now: PushButton = self.ui.findChild(PushButton, "pushButton_runnow")
# self.run_now.setIcon(FluentIcon.PLAY)
# self.run_now.clicked.connect(lambda: self.maa_starter("日常代理"))
self.check_start: PushButton = self.ui.findChild(
PushButton, "pushButton_checkstart"
)
self.check_start.setIcon(FluentIcon.PLAY)
self.check_start.clicked.connect(lambda: self.maa_starter("人工排查"))
# self.check_start: PushButton = self.ui.findChild(
# PushButton, "pushButton_checkstart"
# )
# self.check_start.setIcon(FluentIcon.PLAY)
# self.check_start.clicked.connect(lambda: self.maa_starter("人工排查"))
self.maa_path: LineEdit = self.ui.findChild(LineEdit, "lineEdit_MAApath")
self.maa_path.textChanged.connect(self.change_config)
self.maa_path.setReadOnly(True)
# self.maa_path: LineEdit = self.ui.findChild(LineEdit, "lineEdit_MAApath")
# self.maa_path.textChanged.connect(self.change_config)
# self.maa_path.setReadOnly(True)
self.get_maa_path: PushButton = self.ui.findChild(
PushButton, "pushButton_getMAApath"
)
self.get_maa_path.setIcon(FluentIcon.FOLDER)
self.get_maa_path.clicked.connect(lambda: self.read("file_path_maa"))
# self.get_maa_path: PushButton = self.ui.findChild(
# PushButton, "pushButton_getMAApath"
# )
# self.get_maa_path.setIcon(FluentIcon.FOLDER)
# self.get_maa_path.clicked.connect(lambda: self.read("file_path_maa"))
self.set_maa: PushButton = self.ui.findChild(PushButton, "pushButton_setMAA")
self.set_maa.setIcon(FluentIcon.SETTING)
self.set_maa.clicked.connect(lambda: self.maa_starter("设置MAA_全局"))
# self.set_maa: PushButton = self.ui.findChild(PushButton, "pushButton_setMAA")
# self.set_maa.setIcon(FluentIcon.SETTING)
# self.set_maa.clicked.connect(lambda: self.maa_starter("设置MAA_全局"))
self.routine: SpinBox = self.ui.findChild(SpinBox, "spinBox_routine")
self.routine.valueChanged.connect(self.change_config)
# self.routine: SpinBox = self.ui.findChild(SpinBox, "spinBox_routine")
# self.routine.valueChanged.connect(self.change_config)
self.annihilation: SpinBox = self.ui.findChild(SpinBox, "spinBox_annihilation")
self.annihilation.valueChanged.connect(self.change_config)
# self.annihilation: SpinBox = self.ui.findChild(SpinBox, "spinBox_annihilation")
# self.annihilation.valueChanged.connect(self.change_config)
self.num: SpinBox = self.ui.findChild(SpinBox, "spinBox_numt")
self.num.valueChanged.connect(self.change_config)
# self.num: SpinBox = self.ui.findChild(SpinBox, "spinBox_numt")
# self.num.valueChanged.connect(self.change_config)
self.if_self_start: CheckBox = self.ui.findChild(
CheckBox, "checkBox_ifselfstart"
)
self.if_self_start.stateChanged.connect(self.change_config)
# self.if_self_start: CheckBox = self.ui.findChild(
# CheckBox, "checkBox_ifselfstart"
# )
# self.if_self_start.stateChanged.connect(self.change_config)
self.if_sleep: CheckBox = self.ui.findChild(CheckBox, "checkBox_ifsleep")
self.if_sleep.stateChanged.connect(self.change_config)
# self.if_sleep: CheckBox = self.ui.findChild(CheckBox, "checkBox_ifsleep")
# self.if_sleep.stateChanged.connect(self.change_config)
self.if_proxy_directly: CheckBox = self.ui.findChild(
CheckBox, "checkBox_ifproxydirectly"
)
self.if_proxy_directly.stateChanged.connect(self.change_config)
# self.if_proxy_directly: CheckBox = self.ui.findChild(
# CheckBox, "checkBox_ifproxydirectly"
# )
# self.if_proxy_directly.stateChanged.connect(self.change_config)
self.if_send_mail: CheckBox = self.ui.findChild(CheckBox, "checkBox_ifsendmail")
self.if_send_mail.stateChanged.connect(self.change_config)
# self.if_send_mail: CheckBox = self.ui.findChild(CheckBox, "checkBox_ifsendmail")
# self.if_send_mail.stateChanged.connect(self.change_config)
self.mail_address: LineEdit = self.ui.findChild(
LineEdit, "lineEdit_mailaddress"
)
self.mail_address.textChanged.connect(self.change_config)
# self.mail_address: LineEdit = self.ui.findChild(
# LineEdit, "lineEdit_mailaddress"
# )
# self.mail_address.textChanged.connect(self.change_config)
self.if_send_error_only: CheckBox = self.ui.findChild(
CheckBox, "checkBox_ifonlyerror"
)
self.if_send_error_only.stateChanged.connect(self.change_config)
# self.if_send_error_only: CheckBox = self.ui.findChild(
# CheckBox, "checkBox_ifonlyerror"
# )
# self.if_send_error_only.stateChanged.connect(self.change_config)
self.if_silence: CheckBox = self.ui.findChild(CheckBox, "checkBox_silence")
self.if_silence.stateChanged.connect(self.change_config)
# self.if_silence: CheckBox = self.ui.findChild(CheckBox, "checkBox_silence")
# self.if_silence.stateChanged.connect(self.change_config)
self.boss_key: LineEdit = self.ui.findChild(LineEdit, "lineEdit_boss")
self.boss_key.textChanged.connect(self.change_config)
# self.boss_key: LineEdit = self.ui.findChild(LineEdit, "lineEdit_boss")
# self.boss_key.textChanged.connect(self.change_config)
self.if_to_tray: CheckBox = self.ui.findChild(CheckBox, "checkBox_iftotray")
self.if_to_tray.stateChanged.connect(self.change_config)
# self.if_to_tray: CheckBox = self.ui.findChild(CheckBox, "checkBox_iftotray")
# self.if_to_tray.stateChanged.connect(self.change_config)
self.check_update: PushButton = self.ui.findChild(
PushButton, "pushButton_check_update"
)
self.check_update.setIcon(FluentIcon.UPDATE)
self.check_update.clicked.connect(self.check_version)
# self.check_update: PushButton = self.ui.findChild(
# PushButton, "pushButton_check_update"
# )
# self.check_update.setIcon(FluentIcon.UPDATE)
# self.check_update.clicked.connect(self.check_version)
self.tips: TextBrowser = self.ui.findChild(TextBrowser, "textBrowser_tips")
self.tips.setOpenExternalLinks(True)
# self.tips: TextBrowser = self.ui.findChild(TextBrowser, "textBrowser_tips")
# self.tips.setOpenExternalLinks(True)
self.run_text: TextBrowser = self.ui.findChild(TextBrowser, "textBrowser_run")
self.wait_text: TextBrowser = self.ui.findChild(TextBrowser, "textBrowser_wait")
self.over_text: TextBrowser = self.ui.findChild(TextBrowser, "textBrowser_over")
self.error_text: TextBrowser = self.ui.findChild(
TextBrowser, "textBrowser_error"
)
self.log_text: TextBrowser = self.ui.findChild(TextBrowser, "textBrowser_log")
# self.run_text: TextBrowser = self.ui.findChild(TextBrowser, "textBrowser_run")
# self.wait_text: TextBrowser = self.ui.findChild(TextBrowser, "textBrowser_wait")
# self.over_text: TextBrowser = self.ui.findChild(TextBrowser, "textBrowser_over")
# self.error_text: TextBrowser = self.ui.findChild(
# TextBrowser, "textBrowser_error"
# )
# self.log_text: TextBrowser = self.ui.findChild(TextBrowser, "textBrowser_log")
self.start_time: List[Tuple[CheckBox, TimePicker]] = []
for i in range(10):
self.start_time.append(
[
self.ui.findChild(CheckBox, f"checkBox_t{i + 1}"),
self.ui.findChild(TimePicker, f"timeEdit_{i + 1}"),
]
)
self.start_time[i][0].stateChanged.connect(self.change_config)
self.start_time[i][1].timeChanged.connect(self.change_config)
# self.start_time: List[Tuple[CheckBox, TimePicker]] = []
# for i in range(10):
# self.start_time.append(
# [
# self.ui.findChild(CheckBox, f"checkBox_t{i + 1}"),
# self.ui.findChild(TimePicker, f"timeEdit_{i + 1}"),
# ]
# )
# self.start_time[i][0].stateChanged.connect(self.change_config)
# self.start_time[i][1].timeChanged.connect(self.change_config)
self.change_password: PushButton = self.ui.findChild(
PushButton, "pushButton_changePASSWORD"
)
self.change_password.setIcon(FluentIcon.VPN)
self.change_password.clicked.connect(self.change_PASSWORD)
# self.change_password: PushButton = self.ui.findChild(
# PushButton, "pushButton_changePASSWORD"
# )
# self.change_password.setIcon(FluentIcon.VPN)
# self.change_password.clicked.connect(self.change_PASSWORD)
# 初始化线程
self.MaaManager = MaaManager(self.config)
@@ -332,16 +247,16 @@ class Main(QWidget):
self.MaaManager.get_json.connect(self.get_maa_config)
self.MaaManager.set_silence.connect(self.switch_silence)
self.last_time = "0000-00-00 00:00"
self.Timer = QtCore.QTimer()
self.Timer.timeout.connect(self.set_theme)
self.Timer.timeout.connect(self.set_system)
self.Timer.timeout.connect(self.timed_start)
self.Timer.start(1000)
# self.last_time = "0000-00-00 00:00"
# self.Timer = QtCore.QTimer()
# self.Timer.timeout.connect(self.set_theme)
# self.Timer.timeout.connect(self.set_system)
# self.Timer.timeout.connect(self.timed_start)
# self.Timer.start(1000)
# 载入GUI数据
self.update_user_info("normal")
self.update_config()
# self.update_user_info("normal")
# self.update_config()
# 启动后直接开始代理
if self.config.content["Default"]["SelfSet.IfProxyDirectly"] == "True":
@@ -365,86 +280,6 @@ class Main(QWidget):
if choice.exec():
break
def change_PASSWORD(self) -> None:
"""修改管理密钥"""
# 获取用户信息
self.config.cur.execute("SELECT * FROM adminx WHERE True")
data = self.config.cur.fetchall()
if len(data) == 0:
choice = MessageBox("验证通过", "当前无用户,验证自动通过", self.ui)
choice.cancelButton.hide()
choice.buttonLayout.insertStretch(1)
# 获取新的管理密钥
if choice.exec():
while True:
PASSWORD_new = self.read("newkey")
if PASSWORD_new == None:
choice = MessageBox(
"确认",
"您没有输入新的管理密钥,是否取消修改管理密钥?",
self.ui,
)
if choice.exec():
break
else:
# 修改管理密钥
self.PASSWORD = PASSWORD_new
self.crypto.get_PASSWORD(self.PASSWORD)
choice = MessageBox("操作成功", "管理密钥修改成功", self.ui)
choice.cancelButton.hide()
choice.buttonLayout.insertStretch(1)
if choice.exec():
break
else:
# 验证管理密钥
if_change = True
while if_change:
if self.read("oldkey"):
# 验证旧管理密钥
if not self.crypto.check_PASSWORD(self.PASSWORD):
choice = MessageBox("错误", "管理密钥错误", self.ui)
choice.cancelButton.hide()
choice.buttonLayout.insertStretch(1)
if choice.exec():
pass
else:
# 获取新的管理密钥
while True:
PASSWORD_new = self.read("newkey")
if PASSWORD_new == None:
choice = MessageBox(
"确认",
"您没有输入新的管理密钥,是否取消修改管理密钥?",
self.ui,
)
if choice.exec():
if_change = False
break
# 修改管理密钥
else:
self.crypto.change_PASSWORD(
data, self.PASSWORD, PASSWORD_new
)
self.PASSWORD = PASSWORD_new
choice = MessageBox(
"操作成功", "管理密钥修改成功", self.ui
)
choice.cancelButton.hide()
choice.buttonLayout.insertStretch(1)
if choice.exec():
if_change = False
break
else:
choice = MessageBox(
"确认",
"您没有输入管理密钥,是否取消修改管理密钥?",
self.ui,
)
if choice.exec():
break
def update_user_info(self, operation: str) -> None:
"""将本地数据库中的用户配置同步至GUI的用户管理界面"""
@@ -1518,111 +1353,6 @@ class Main(QWidget):
self.run_now.setEnabled(True)
self.check_start.setEnabled(True)
def check_version(self):
"""检查版本更新,调起文件下载进程"""
# 从本地版本信息文件获取当前版本信息
with self.config.version_path.open(mode="r", encoding="utf-8") as f:
version_current = json.load(f)
main_version_current = list(
map(int, version_current["main_version"].split("."))
)
updater_version_current = list(
map(int, version_current["updater_version"].split("."))
)
# 检查更新器是否存在
if not (self.config.app_path / "Updater.exe").exists():
updater_version_current = [0, 0, 0, 0]
# 从远程服务器获取最新版本信息
for _ in range(3):
try:
response = requests.get(
"https://gitee.com/DLmaster_361/AUTO_MAA/raw/main/resources/version.json"
)
version_remote = response.json()
break
except Exception as e:
err = e
time.sleep(0.1)
else:
choice = MessageBox(
"错误",
f"获取版本信息时出错:\n{err}",
self.ui,
)
choice.cancelButton.hide()
choice.buttonLayout.insertStretch(1)
if choice.exec():
return None
main_version_remote = list(map(int, version_remote["main_version"].split(".")))
updater_version_remote = list(
map(int, version_remote["updater_version"].split("."))
)
# 有版本更新
if (main_version_remote > main_version_current) or (
updater_version_remote > updater_version_current
):
# 生成版本更新信息
if main_version_remote > main_version_current:
main_version_info = f" 主程序:{version_text(main_version_current)} --> {version_text(main_version_remote)}\n"
else:
main_version_info = (
f" 主程序:{version_text(main_version_current)}\n"
)
if updater_version_remote > updater_version_current:
updater_version_info = f" 更新器:{version_text(updater_version_current)} --> {version_text(updater_version_remote)}\n"
else:
updater_version_info = (
f" 更新器:{version_text(updater_version_current)}\n"
)
# 询问是否开始版本更新
choice = MessageBox(
"版本更新",
f"发现新版本:\n{main_version_info}{updater_version_info} 更新说明:\n{version_remote['announcement'].replace("\n# ","\n ").replace("\n## ","\n - ").replace("\n- ","\n · ")}\n\n是否开始更新?\n\n 注意主程序更新时AUTO_MAA将自动关闭",
self.ui,
)
if not choice.exec():
return None
# 更新更新器
if updater_version_remote > updater_version_current:
# 创建更新进程
self.updater = Updater(
self.config.app_path,
"AUTO_MAA更新器",
main_version_remote,
updater_version_remote,
)
# 完成更新器的更新后更新主程序
if main_version_remote > main_version_current:
self.updater.update_process.accomplish.connect(self.update_main)
# 显示更新页面
self.updater.ui.show()
# 更新主程序
elif main_version_remote > main_version_current:
self.update_main()
# 无版本更新
else:
self.notify.push_notification("已是最新版本~", " ", " ", 3)
def update_main(self):
"""更新主程序"""
subprocess.Popen(
str(self.config.app_path / "Updater.exe"),
shell=True,
creationflags=subprocess.CREATE_NO_WINDOW,
)
self.close()
QApplication.quit()
def server_date(self):
"""获取当前的服务器日期"""
@@ -1630,194 +1360,3 @@ class Main(QWidget):
if dt.time() < datetime.datetime.min.time().replace(hour=4):
dt = dt - datetime.timedelta(days=1)
return dt.strftime("%Y-%m-%d")
class AUTO_MAA(QMainWindow):
if_save = True
def __init__(self, config: AppConfig, notify: Notification, crypto: CryptoHandler):
super(AUTO_MAA, self).__init__()
self.config = config
self.notify = notify
self.config.open_database()
# 创建主窗口
self.main = Main(config=config, notify=notify, crypto=crypto)
self.setCentralWidget(self.main.ui)
self.setWindowIcon(
QIcon(str(self.config.app_path / "resources/icons/AUTO_MAA.ico"))
)
self.setWindowTitle("AUTO_MAA")
# 创建系统托盘及其菜单
self.tray = QSystemTrayIcon(
QIcon(str(self.config.app_path / "resources/icons/AUTO_MAA.ico")),
self,
)
self.tray.setToolTip("AUTO_MAA")
self.tray_menu = RoundMenu()
# 显示主界面菜单项
self.tray_menu.addAction(
Action(FluentIcon.CAFE, "显示主界面", triggered=self.show_main)
)
self.tray_menu.addSeparator()
# 开始任务菜单项
self.tray_menu.addActions(
[
Action(
FluentIcon.PLAY,
"运行日常代理",
triggered=lambda: self.start_task("日常代理"),
),
# Action(
# FluentIcon.PLAY,
# "运行人工排查",
# triggered=lambda: self.start_task("人工排查"),
# ),
Action(FluentIcon.PAUSE, "中止当前任务", triggered=self.stop_task),
]
)
self.tray_menu.addSeparator()
# 退出主程序菜单项
self.tray_menu.addAction(
Action(FluentIcon.POWER_BUTTON, "退出主程序", triggered=self.kill_main)
)
# 设置托盘菜单
self.tray.setContextMenu(self.tray_menu)
self.tray.activated.connect(self.on_tray_activated)
self.show_main()
def show_tray(self):
"""最小化到托盘"""
if self.if_save:
self.set_ui("保存")
self.hide()
self.tray.show()
def show_main(self):
"""显示主界面"""
self.set_ui("配置")
self.tray.hide()
def on_tray_activated(self, reason):
"""双击返回主界面"""
if reason == QSystemTrayIcon.DoubleClick:
self.show_main()
def start_task(self, mode):
"""调起对应任务"""
if self.main.MaaManager.isRunning():
self.notify.push_notification(
f"无法运行{mode}",
"当前已有任务正在运行,请在该任务结束后重试",
"当前已有任务正在运行,请在该任务结束后重试",
3,
)
else:
self.main.maa_starter(mode)
def stop_task(self):
"""中止当前任务"""
if self.main.MaaManager.isRunning():
if (
self.main.MaaManager.mode == "日常代理"
or self.main.MaaManager.mode == "人工排查"
):
self.main.maa_ender(f"{self.main.MaaManager.mode}_结束")
elif "设置MAA" in self.main.MaaManager.mode:
self.notify.push_notification(
"正在设置MAA",
"正在运行设置MAA任务无法中止",
"正在运行设置MAA任务无法中止",
3,
)
else:
self.notify.push_notification(
"无任务运行!",
"当前无任务正在运行,无需中止",
"当前无任务正在运行,无需中止",
3,
)
def kill_main(self):
"""退出主程序"""
self.close()
QApplication.quit()
def set_ui(self, mode):
"""设置窗口相关属性"""
# 保存窗口相关属性
if mode == "保存":
self.config.content["Default"][
"SelfSet.UIsize"
] = f"{self.geometry().width()}x{self.geometry().height()}"
self.config.content["Default"][
"SelfSet.UIlocation"
] = f"{self.geometry().x()}x{self.geometry().y()}"
if self.isMaximized():
self.config.content["Default"]["SelfSet.UImaximized"] = "True"
else:
self.config.content["Default"]["SelfSet.UImaximized"] = "False"
self.config.save_config()
# 配置窗口相关属性
elif mode == "配置":
self.if_save = False
size = list(
map(int, self.config.content["Default"]["SelfSet.UIsize"].split("x"))
)
location = list(
map(
int, self.config.content["Default"]["SelfSet.UIlocation"].split("x")
)
)
self.setGeometry(location[0], location[1], size[0], size[1])
if self.config.content["Default"]["SelfSet.UImaximized"] == "True":
self.showMinimized()
self.showMaximized()
else:
self.showMinimized()
self.showNormal()
self.if_save = True
def changeEvent(self, event: QtCore.QEvent):
"""重写后的 changeEvent"""
# 最小化到托盘功能实现
if event.type() == QtCore.QEvent.WindowStateChange:
if self.windowState() & QtCore.Qt.WindowMinimized:
if self.config.content["Default"]["SelfSet.IfToTray"] == "True":
self.show_tray()
# 保留其它 changeEvent 方法
return super().changeEvent(event)
def closeEvent(self, event: QCloseEvent):
"""清理残余进程"""
self.set_ui("保存")
# 清理各功能线程
self.main.Timer.stop()
self.main.Timer.deleteLater()
self.main.MaaManager.requestInterruption()
self.main.MaaManager.quit()
self.main.MaaManager.wait()
# 关闭数据库连接
self.config.close_database()
event.accept()

312
app/ui/main_window.py Normal file
View File

@@ -0,0 +1,312 @@
# <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,
)
from qfluentwidgets import (
Action,
PushButton,
LineEdit,
PasswordLineEdit,
TextBrowser,
TableWidget,
TimePicker,
SystemTrayMenu,
ComboBox,
CheckBox,
SpinBox,
FluentIcon,
RoundMenu,
MessageBox,
MessageBoxBase,
HeaderCardWidget,
BodyLabel,
Dialog,
SingleDirectionScrollArea,
SubtitleLabel,
MSFluentWindow,
NavigationItemPosition,
)
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 json
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
from .setting import Setting
from .member_manager import MemberManager
class AUTO_MAA(MSFluentWindow):
if_save = True
def __init__(self, config: AppConfig, notify: Notification, crypto: CryptoHandler):
super(AUTO_MAA, self).__init__()
self.config = config
self.notify = notify
self.config.open_database()
# 创建主窗口
self.setting = Setting(config=config, notify=notify, crypto=crypto)
self.member_manager = MemberManager(config=config, notify=notify, crypto=crypto)
self.addSubInterface(
self.setting,
FluentIcon.SETTING,
"设置",
FluentIcon.SETTING,
NavigationItemPosition.BOTTOM,
)
self.addSubInterface(
self.member_manager,
FluentIcon.ROBOT,
"脚本管理",
FluentIcon.ROBOT,
NavigationItemPosition.TOP,
)
self.setWindowIcon(
QIcon(str(self.config.app_path / "resources/icons/AUTO_MAA.ico"))
)
self.setWindowTitle("AUTO_MAA")
# 创建系统托盘及其菜单
self.tray = QSystemTrayIcon(
QIcon(str(self.config.app_path / "resources/icons/AUTO_MAA.ico")),
self,
)
self.tray.setToolTip("AUTO_MAA")
self.tray_menu = SystemTrayMenu()
# 显示主界面菜单项
self.tray_menu.addAction(
Action(FluentIcon.CAFE, "显示主界面", triggered=self.show_main)
)
self.tray_menu.addSeparator()
# 开始任务菜单项
# self.tray_menu.addActions(
# [
# Action(
# FluentIcon.PLAY,
# "运行日常代理",
# triggered=lambda: self.start_task("日常代理"),
# ),
# Action(
# FluentIcon.PLAY,
# "运行人工排查",
# triggered=lambda: self.start_task("人工排查"),
# ),
# Action(FluentIcon.PAUSE, "中止当前任务", triggered=self.stop_task),
# ]
# )
# self.tray_menu.addSeparator()
# 退出主程序菜单项
self.tray_menu.addAction(
Action(FluentIcon.POWER_BUTTON, "退出主程序", triggered=self.kill_main)
)
# 设置托盘菜单
self.tray.setContextMenu(self.tray_menu)
self.tray.activated.connect(self.on_tray_activated)
self.show_main()
def show_tray(self):
"""最小化到托盘"""
if self.if_save:
self.set_ui("保存")
self.hide()
self.tray.show()
def show_main(self):
"""显示主界面"""
self.set_ui("配置")
self.tray.hide()
def on_tray_activated(self, reason):
"""双击返回主界面"""
if reason == QSystemTrayIcon.DoubleClick:
self.show_main()
def start_task(self, mode):
"""调起对应任务"""
if self.main.MaaManager.isRunning():
self.notify.push_notification(
f"无法运行{mode}",
"当前已有任务正在运行,请在该任务结束后重试",
"当前已有任务正在运行,请在该任务结束后重试",
3,
)
else:
self.main.maa_starter(mode)
def stop_task(self):
"""中止当前任务"""
if self.main.MaaManager.isRunning():
if (
self.main.MaaManager.mode == "日常代理"
or self.main.MaaManager.mode == "人工排查"
):
self.main.maa_ender(f"{self.main.MaaManager.mode}_结束")
elif "设置MAA" in self.main.MaaManager.mode:
self.notify.push_notification(
"正在设置MAA",
"正在运行设置MAA任务无法中止",
"正在运行设置MAA任务无法中止",
3,
)
else:
self.notify.push_notification(
"无任务运行!",
"当前无任务正在运行,无需中止",
"当前无任务正在运行,无需中止",
3,
)
def kill_main(self):
"""退出主程序"""
self.close()
QApplication.quit()
def set_ui(self, mode):
"""设置窗口相关属性"""
# 保存窗口相关属性
if mode == "保存":
self.config.global_config.set(
self.config.global_config.ui_size,
f"{self.geometry().width()}x{self.geometry().height()}",
)
self.config.global_config.set(
self.config.global_config.ui_location,
f"{self.geometry().x()}x{self.geometry().y()}",
)
if self.isMaximized():
self.config.global_config.set(
self.config.global_config.ui_maximized, True
)
else:
self.config.global_config.set(
self.config.global_config.ui_maximized, False
)
self.config.global_config.save()
# 配置窗口相关属性
elif mode == "配置":
self.if_save = False
size = list(
map(
int,
self.config.global_config.get(
self.config.global_config.ui_size
).split("x"),
)
)
location = list(
map(
int,
self.config.global_config.get(
self.config.global_config.ui_location
).split("x"),
)
)
self.setGeometry(location[0], location[1], size[0], size[1])
if self.config.global_config.get(self.config.global_config.ui_maximized):
self.showMinimized()
self.showMaximized()
else:
self.showMinimized()
self.showNormal()
self.if_save = True
def changeEvent(self, event: QtCore.QEvent):
"""重写后的 changeEvent"""
# 最小化到托盘功能实现
if event.type() == QtCore.QEvent.WindowStateChange:
if self.windowState() & QtCore.Qt.WindowMinimized:
if self.config.global_config.get(self.config.global_config.ui_IfToTray):
self.show_tray()
# 保留其它 changeEvent 方法
return super().changeEvent(event)
def closeEvent(self, event: QCloseEvent):
"""清理残余进程"""
self.set_ui("保存")
# 清理各功能线程
# self.main.Timer.stop()
# self.main.Timer.deleteLater()
# self.main.MaaManager.requestInterruption()
# self.main.MaaManager.quit()
# self.main.MaaManager.wait()
# 关闭数据库连接
self.config.close_database()
event.accept()

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)

623
app/ui/setting.py Normal file
View File

@@ -0,0 +1,623 @@
# <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,
QHBoxLayout,
)
from qfluentwidgets import (
Action,
PushButton,
LineEdit,
PasswordLineEdit,
TextBrowser,
TableWidget,
TimePicker,
ComboBox,
CheckBox,
ScrollArea,
SpinBox,
FluentIcon,
SwitchButton,
RoundMenu,
MessageBox,
MessageBoxBase,
HeaderCardWidget,
BodyLabel,
Dialog,
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 json
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
from app.services import Notification, CryptoHandler
from app.utils import Updater, version_text
from .Widget import InputMessageBox, LineEditSettingCard
class Setting(QWidget):
def __init__(self, config: AppConfig, notify: Notification, crypto: CryptoHandler):
super(Setting, self).__init__()
self.setObjectName("设置")
self.config = config
self.notify = notify
self.crypto = crypto
layout = QVBoxLayout()
scrollArea = ScrollArea()
scrollArea.setWidgetResizable(True)
content_widget = QWidget()
content_layout = QVBoxLayout(content_widget)
self.function = FunctionSettingCard(self, self.config)
self.start = StartSettingCard(self, self.config)
self.ui = UiSettingCard(self, self.config)
self.notification = NotifySettingCard(self, self.config)
self.security = SecuritySettingCard(self)
self.updater = UpdaterSettingCard(self, self.config)
self.other = OtherSettingCard(self, self.config)
self.security.card_changePASSWORD.clicked.connect(self.change_PASSWORD)
self.updater.card_CheckUpdate.clicked.connect(self.check_version)
self.other.card_Tips.clicked.connect(self.show_tips)
content_layout.addWidget(self.function)
content_layout.addWidget(self.start)
content_layout.addWidget(self.ui)
content_layout.addWidget(self.notification)
content_layout.addWidget(self.security)
content_layout.addWidget(self.updater)
content_layout.addWidget(self.other)
scrollArea.setWidget(content_widget)
layout.addWidget(scrollArea)
self.setLayout(layout)
def check_PASSWORD(self) -> None:
"""检查并配置管理密钥"""
if self.config.key_path.exists():
return None
while True:
choice = InputMessageBox(
self,
"未检测到管理密钥,请设置您的管理密钥",
"管理密钥",
"密码",
)
if choice.exec() and choice.input.text() != "":
self.crypto.get_PASSWORD(choice.input.text())
break
else:
choice = MessageBox(
"确认", "您没有输入管理密钥,确定要暂时跳过这一步吗?", self
)
if choice.exec():
break
def change_PASSWORD(self) -> None:
"""修改管理密钥"""
# 获取用户信息
self.config.cur.execute("SELECT * FROM adminx WHERE True")
data = self.config.cur.fetchall()
if len(data) == 0:
choice = MessageBox("验证通过", "当前无用户,验证自动通过", self)
choice.cancelButton.hide()
choice.buttonLayout.insertStretch(1)
# 获取新的管理密钥
if choice.exec():
while True:
a = InputMessageBox(
self, "请输入新的管理密钥", "新管理密钥", "密码"
)
if a.exec() and a.input.text() != "":
# 修改管理密钥
self.crypto.get_PASSWORD(a.input.text())
choice = MessageBox("操作成功", "管理密钥修改成功", self)
choice.cancelButton.hide()
choice.buttonLayout.insertStretch(1)
if choice.exec():
break
else:
choice = MessageBox(
"确认",
"您没有输入新的管理密钥,是否取消修改管理密钥?",
self,
)
if choice.exec():
break
else:
# 验证管理密钥
if_change = True
while if_change:
choice = InputMessageBox(
self, "请输入旧的管理密钥", "旧管理密钥", "密码"
)
if choice.exec() and choice.input.text() != "":
# 验证旧管理密钥
if self.crypto.check_PASSWORD(choice.input.text()):
PASSWORD_old = choice.input.text()
# 获取新的管理密钥
while True:
choice = InputMessageBox(
self, "请输入新的管理密钥", "新管理密钥", "密码"
)
if choice.exec() and choice.input.text() != "":
# 修改管理密钥
self.crypto.change_PASSWORD(
data, PASSWORD_old, choice.input.text()
)
choice = MessageBox(
"操作成功", "管理密钥修改成功", self
)
choice.cancelButton.hide()
choice.buttonLayout.insertStretch(1)
if choice.exec():
if_change = False
break
else:
choice = MessageBox(
"确认",
"您没有输入新的管理密钥,是否取消修改管理密钥?",
self,
)
if choice.exec():
if_change = False
break
else:
choice = MessageBox("错误", "管理密钥错误", self)
choice.cancelButton.hide()
choice.buttonLayout.insertStretch(1)
if choice.exec():
pass
else:
choice = MessageBox(
"确认",
"您没有输入管理密钥,是否取消修改管理密钥?",
self,
)
if choice.exec():
break
def check_version(self):
"""检查版本更新,调起文件下载进程"""
# 从本地版本信息文件获取当前版本信息
with self.config.version_path.open(mode="r", encoding="utf-8") as f:
version_current = json.load(f)
main_version_current = list(
map(int, version_current["main_version"].split("."))
)
updater_version_current = list(
map(int, version_current["updater_version"].split("."))
)
# 检查更新器是否存在
if not (self.config.app_path / "Updater.exe").exists():
updater_version_current = [0, 0, 0, 0]
# 从远程服务器获取最新版本信息
for _ in range(3):
try:
response = requests.get(
"https://gitee.com/DLmaster_361/AUTO_MAA/raw/main/resources/version.json"
)
version_remote = response.json()
break
except Exception as e:
err = e
time.sleep(0.1)
else:
choice = MessageBox(
"错误",
f"获取版本信息时出错:\n{err}",
self,
)
choice.cancelButton.hide()
choice.buttonLayout.insertStretch(1)
if choice.exec():
return None
main_version_remote = list(map(int, version_remote["main_version"].split(".")))
updater_version_remote = list(
map(int, version_remote["updater_version"].split("."))
)
# 有版本更新
if (main_version_remote > main_version_current) or (
updater_version_remote > updater_version_current
):
# 生成版本更新信息
if main_version_remote > main_version_current:
main_version_info = f" 主程序:{version_text(main_version_current)} --> {version_text(main_version_remote)}\n"
else:
main_version_info = (
f" 主程序:{version_text(main_version_current)}\n"
)
if updater_version_remote > updater_version_current:
updater_version_info = f" 更新器:{version_text(updater_version_current)} --> {version_text(updater_version_remote)}\n"
else:
updater_version_info = (
f" 更新器:{version_text(updater_version_current)}\n"
)
# 询问是否开始版本更新
choice = MessageBox(
"版本更新",
f"发现新版本:\n{main_version_info}{updater_version_info} 更新说明:\n{version_remote['announcement'].replace("\n# ","\n ").replace("\n## ","\n - ").replace("\n- ","\n · ")}\n\n是否开始更新?\n\n 注意主程序更新时AUTO_MAA将自动关闭",
self,
)
if not choice.exec():
return None
# 更新更新器
if updater_version_remote > updater_version_current:
# 创建更新进程
self.updater = Updater(
self.config.app_path,
"AUTO_MAA更新器",
main_version_remote,
updater_version_remote,
)
# 完成更新器的更新后更新主程序
if main_version_remote > main_version_current:
self.updater.update_process.accomplish.connect(self.update_main)
# 显示更新页面
self.updater.ui.show()
# 更新主程序
elif main_version_remote > main_version_current:
self.update_main()
# 无版本更新
else:
self.notify.push_notification("已是最新版本~", " ", " ", 3)
def update_main(self):
"""更新主程序"""
subprocess.Popen(
str(self.config.app_path / "Updater.exe"),
shell=True,
creationflags=subprocess.CREATE_NO_WINDOW,
)
self.close()
QApplication.quit()
def show_tips(self):
"""显示小贴士"""
choice = MessageBox("小贴士", "这里什么都没有~", self)
choice.cancelButton.hide()
choice.buttonLayout.insertStretch(1)
if choice.exec():
pass
class FunctionSettingCard(HeaderCardWidget):
def __init__(self, parent=None, config: AppConfig = None):
super().__init__(parent)
self.setTitle("功能")
self.config = config.global_config
Layout = QVBoxLayout()
self.card_IfSleep = SwitchSettingCard(
icon=FluentIcon.PAGE_RIGHT,
title="启动时阻止系统休眠",
content="仅阻止电脑自动休眠,不会影响屏幕是否熄灭",
configItem=self.config.function_IfSleep,
)
self.card_IfSilence = SwitchSettingCard(
icon=FluentIcon.PAGE_RIGHT,
title="静默模式",
content="将各代理窗口置于后台运行,减少对前台的干扰",
configItem=self.config.function_IfSilence,
)
# 添加各组到设置卡中
Layout.addWidget(self.card_IfSleep)
Layout.addWidget(self.card_IfSilence)
self.viewLayout.addLayout(Layout)
class StartSettingCard(HeaderCardWidget):
def __init__(self, parent=None, config: AppConfig = None):
super().__init__(parent)
self.setTitle("启动")
self.config = config.global_config
Layout = QVBoxLayout()
self.card_IfSelfStart = SwitchSettingCard(
icon=FluentIcon.PAGE_RIGHT,
title="开机时自动启动",
content="将AUTO_MAA添加到开机启动项",
configItem=self.config.start_IfSelfStart,
)
self.card_IfRunDirectly = SwitchSettingCard(
icon=FluentIcon.PAGE_RIGHT,
title="启动后直接运行",
content="启动AUTO_MAA后自动运行任务",
configItem=self.config.start_IfRunDirectly,
)
# 添加各组到设置卡中
Layout.addWidget(
self.card_IfSelfStart,
)
Layout.addWidget(self.card_IfRunDirectly)
self.viewLayout.addLayout(Layout)
class UiSettingCard(HeaderCardWidget):
def __init__(self, parent=None, config: AppConfig = None):
super().__init__(parent)
self.setTitle("界面")
self.config = config.global_config
Layout = QVBoxLayout()
self.card_IfShowTray = SwitchSettingCard(
icon=FluentIcon.PAGE_RIGHT,
title="显示托盘图标",
content="常态显示托盘图标",
configItem=self.config.ui_IfShowTray,
)
self.card_IfToTray = SwitchSettingCard(
icon=FluentIcon.PAGE_RIGHT,
title="最小化到托盘",
content="最小化时隐藏到托盘",
configItem=self.config.ui_IfToTray,
)
# 添加各组到设置卡中
Layout.addWidget(self.card_IfShowTray)
Layout.addWidget(self.card_IfToTray)
self.viewLayout.addLayout(Layout)
class NotifySettingCard(HeaderCardWidget):
def __init__(self, parent=None, config: AppConfig = None):
super().__init__(parent)
self.setTitle("通知")
self.config = config
Layout = QVBoxLayout()
self.card_IfPushPlyer = SwitchSettingCard(
icon=FluentIcon.PAGE_RIGHT,
title="推送系统通知",
content="推送系统级通知,不会在通知中心停留",
configItem=self.config.global_config.notify_IfPushPlyer,
)
self.card_SendMail = self.SendMailSettingCard(self, self.config)
Layout.addWidget(self.card_IfPushPlyer)
Layout.addWidget(self.card_SendMail)
self.viewLayout.addLayout(Layout)
class SendMailSettingCard(ExpandGroupSettingCard):
def __init__(self, parent=None, config: AppConfig = None):
super().__init__(
FluentIcon.SETTING,
"推送邮件通知",
"通过AUTO_MAA官方通知服务邮箱推送任务结果",
parent,
)
self.config = config.global_config
widget = QWidget()
Layout = QVBoxLayout(widget)
self.card_IfSendMail = SwitchSettingCard(
icon=FluentIcon.PAGE_RIGHT,
title="推送邮件通知",
content="是否启用邮件通知功能",
configItem=self.config.notify_IfSendMail,
)
self.MailAddress = LineEditSettingCard(
text="请输入邮箱地址",
icon=FluentIcon.PAGE_RIGHT,
title="邮箱地址",
content="接收通知的邮箱地址",
configItem=self.config.notify_MailAddress,
)
self.card_IfSendErrorOnly = SwitchSettingCard(
icon=FluentIcon.PAGE_RIGHT,
title="仅推送异常信息",
content="仅在任务出现异常时推送通知",
configItem=self.config.notify_IfSendErrorOnly,
)
Layout.addWidget(self.card_IfSendMail)
Layout.addWidget(self.MailAddress)
Layout.addWidget(self.card_IfSendErrorOnly)
# 调整内部布局
self.viewLayout.setContentsMargins(0, 0, 0, 0)
self.viewLayout.setSpacing(0)
self.addGroupWidget(widget)
class SecuritySettingCard(HeaderCardWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.setTitle("安全")
Layout = QVBoxLayout()
self.card_changePASSWORD = PushSettingCard(
text="修改",
icon=FluentIcon.VPN,
title="修改管理密钥",
content="修改用于解密用户密码的管理密钥",
)
Layout.addWidget(self.card_changePASSWORD)
self.viewLayout.addLayout(Layout)
class UpdaterSettingCard(HeaderCardWidget):
def __init__(self, parent=None, config: AppConfig = None):
super().__init__(parent)
self.setTitle("更新")
self.config = config.global_config
Layout = QVBoxLayout()
self.card_IfAutoUpdate = SwitchSettingCard(
icon=FluentIcon.PAGE_RIGHT,
title="自动检查更新",
content="将在启动时自动检查AUTO_MAA是否有新版本",
configItem=self.config.update_IfAutoUpdate,
)
self.card_CheckUpdate = PushSettingCard(
text="检查更新",
icon=FluentIcon.UPDATE,
title="获取最新版本",
content="检查AUTO_MAA是否有新版本",
)
Layout.addWidget(self.card_IfAutoUpdate)
Layout.addWidget(self.card_CheckUpdate)
self.viewLayout.addLayout(Layout)
class OtherSettingCard(HeaderCardWidget):
def __init__(self, parent=None, config: AppConfig = None):
super().__init__(parent)
self.setTitle("其他")
self.config = config.global_config
Layout = QVBoxLayout()
self.card_Tips = PushSettingCard(
text="查看",
icon=FluentIcon.PAGE_RIGHT,
title="小贴士",
content="查看AUTO_MAA的小贴士",
)
Layout.addWidget(self.card_Tips)
self.viewLayout.addLayout(Layout)

View File

@@ -39,7 +39,7 @@ from PySide6.QtWidgets import (
QDialog,
QVBoxLayout,
)
from qfluentwidgets import ProgressBar, BodyLabel
from qfluentwidgets import ProgressBar, IndeterminateProgressBar, BodyLabel
from PySide6.QtGui import QIcon
from PySide6.QtCore import QObject, QThread, Signal
@@ -262,14 +262,19 @@ class Updater(QObject):
)
# 创建垂直布局
self.Layout_v = QVBoxLayout(self.ui)
self.Layout = QVBoxLayout(self.ui)
self.info = BodyLabel("正在初始化", self.ui)
self.Layout_v.addWidget(self.info)
self.progress_1 = IndeterminateProgressBar(self.ui)
self.progress_2 = ProgressBar(self.ui)
self.progress = ProgressBar(self.ui)
self.progress.setRange(0, 0)
self.Layout_v.addWidget(self.progress)
self.update_progress(0, 0, 0)
self.Layout.addWidget(self.info)
self.Layout.addStretch(1)
self.Layout.addWidget(self.progress_1)
self.Layout.addWidget(self.progress_2)
self.Layout.addStretch(1)
self.update_process = UpdateProcess(
app_path, name, main_version, updater_version
@@ -284,8 +289,14 @@ class Updater(QObject):
self.info.setText(text)
def update_progress(self, begin: int, end: int, current: int) -> None:
self.progress.setRange(begin, end)
self.progress.setValue(current)
if begin == 0 and end == 0:
self.progress_2.setVisible(False)
self.progress_1.setVisible(True)
else:
self.progress_1.setVisible(False)
self.progress_2.setVisible(True)
self.progress_2.setRange(begin, end)
self.progress_2.setValue(current)
class AUTO_MAA_Updater(QApplication):

12
main.py
View File

@@ -26,9 +26,13 @@ v4.2
"""
from PySide6.QtWidgets import QApplication
from qfluentwidgets import FluentTranslator
import sys
from app import AppConfig, Notification, CryptoHandler, AUTO_MAA
from app.config import AppConfig
from app.services.notification import Notification
from app.services.security import CryptoHandler
from app.ui.main_window import AUTO_MAA
if __name__ == "__main__":
@@ -37,6 +41,10 @@ if __name__ == "__main__":
crypto = CryptoHandler(config)
application = QApplication(sys.argv)
translator = FluentTranslator()
application.installTranslator(translator)
window = AUTO_MAA(config=config, notify=notify, crypto=crypto)
window.main.check_PASSWORD()
window.setting.check_PASSWORD()
sys.exit(application.exec())

View File

@@ -1,8 +1,8 @@
{
"main_version": "4.2.0.1",
"updater_version": "1.1.0.1",
"announcement": "\n## 新增功能\n- 初步引入`qfluentwidgets`UI界面美化",
"proxy_list":[
"announcement": "\n# 这是一个预览版本!\n# 这个版本仅能进行用于展示页面,未实现任何功能!!!\n- 若不慎更新到此版本请前往官方仓库下载4.2.0版本压缩包替换本地文件即可回退版本",
"proxy_list": [
"",
"https://gitproxy.click/",
"https://cdn.moran233.xyz/",