设置界面与实例管理界面初步重构
This commit is contained in:
149
app/ui/Widget.py
Normal file
149
app/ui/Widget.py
Normal 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)
|
||||
@@ -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"]
|
||||
|
||||
@@ -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
312
app/ui/main_window.py
Normal 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
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)
|
||||
623
app/ui/setting.py
Normal file
623
app/ui/setting.py
Normal 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)
|
||||
Reference in New Issue
Block a user