diff --git a/src/Core/Config/ConfigModel.py b/src/Core/Config/ConfigModel.py index e1d0f5e..0926a88 100644 --- a/src/Core/Config/ConfigModel.py +++ b/src/Core/Config/ConfigModel.py @@ -61,7 +61,7 @@ class HttpConfig(BaseModel): secret: str enableHeart: bool enablePost: bool - postUrls: List[HttpUrl] + postUrls: List[Optional[HttpUrl]] @field_validator("port") @staticmethod @@ -83,7 +83,7 @@ class WsConfig(BaseModel): class ReverseWsConfig(BaseModel): enable: bool - urls: List[WebsocketUrl] + urls: List[Optional[WebsocketUrl]] class ConnectConfig(BaseModel): @@ -92,10 +92,16 @@ class ConnectConfig(BaseModel): reverseWs: ReverseWsConfig +class NCGroupLocalTime(BaseModel): + Record: bool + RecordList: List[Optional[str]] + + class AdvancedConfig(BaseModel): QQPath: str startScriptPath: str ffmpegPath: str + GroupLocalTime: NCGroupLocalTime debug: bool localFile2url: bool fileLog: bool @@ -108,3 +114,51 @@ class Config(BaseModel): bot: BotConfig connect: ConnectConfig advanced: AdvancedConfig + + +DEFAULT_CONFIG = { + "bot": { + "name": "", + "QQID": "", + "messagePostFormat": "array", + "reportSelfMsg": False, + "musicSignUrl": "", + "heartInterval": "30000", + "accessToken": "", + }, + "connect": { + "http": { + "enable": False, + "host": "", + "port": "", + "secret": "", + "enableHeart": False, + "enablePost": False, + "postUrls": [], + }, + "ws": { + "enable": False, + "host": "", + "port": 3001 + }, + "reverseWs": { + "enable": False, + "urls": [] + }, + }, + "advanced": { + "QQPath": "", + "startScriptPath": "", + "ffmpegPath": "", + "GroupLocalTime": { + "Record": False, + "RecordList": [] + }, + "debug": False, + "localFile2url": False, + "fileLog": False, + "consoleLog": False, + "fileLogLevel": "debug", + "consoleLogLevel": "info" + } +} diff --git a/src/Core/CreateScript.py b/src/Core/CreateScript.py index ca5401b..8c49b93 100644 --- a/src/Core/CreateScript.py +++ b/src/Core/CreateScript.py @@ -230,6 +230,10 @@ def _createConfig(self, bot_config_path: Path, napcat_config_path: Path) -> None "enable": self.config.connect.reverseWs.enable, "urls": [str(url) for url in self.config.connect.reverseWs.urls], }, + "GroupLocalTime": { + "Record": self.config.advanced.GroupLocalTime.Record, + "RecordList": self.config.advanced.GroupLocalTime.RecordList + }, "debug": self.config.advanced.debug, "heartInterval": self.config.bot.heartInterval, "messagePostFormat": self.config.bot.messagePostFormat, diff --git a/src/Ui/AddPage/AddWidget.py b/src/Ui/AddPage/AddWidget.py index d7af332..62f6286 100644 --- a/src/Ui/AddPage/AddWidget.py +++ b/src/Ui/AddPage/AddWidget.py @@ -12,9 +12,8 @@ from src.Ui.AddPage.Advanced import AdvancedWidget from src.Ui.AddPage.BotWidget import BotWidget -from src.Ui.AddPage.Connect import ConnectWidget - from src.Ui.AddPage.ConfigTopCard import ConfigTopCard +from src.Ui.AddPage.Connect import ConnectWidget from src.Ui.StyleSheet import StyleSheet if TYPE_CHECKING: @@ -60,8 +59,8 @@ def _createView(self) -> None: """ self.view = QStackedWidget() self.botWidget = BotWidget(self) - self.connectWidget = ConnectWidget(self) - self.advancedWidget = AdvancedWidget(self) + self.connectWidget = ConnectWidget("Add", self) + self.advancedWidget = AdvancedWidget("Add", self) self.view.addWidget(self.botWidget) self.view.addWidget(self.connectWidget) diff --git a/src/Ui/AddPage/Advanced.py b/src/Ui/AddPage/Advanced.py index 3b3063e..315dcd2 100644 --- a/src/Ui/AddPage/Advanced.py +++ b/src/Ui/AddPage/Advanced.py @@ -1,31 +1,28 @@ # -*- coding: utf-8 -*- -from typing import TYPE_CHECKING - from PySide6.QtCore import Qt from PySide6.QtWidgets import QWidget from creart import it from qfluentwidgets import ExpandLayout, FluentIcon, ScrollArea -from src.Core.PathFunc import PathFunc from src.Core.Config.ConfigModel import AdvancedConfig +from src.Core.PathFunc import PathFunc from src.Ui.common.InputCard import ( SwitchConfigCard, FolderConfigCard, ComboBoxConfigCard, + TextCard ) -if TYPE_CHECKING: - pass - class AdvancedWidget(ScrollArea): """ ## Advance Item 项对应的 QWidget """ - def __init__(self, parent=None, config: AdvancedConfig = None) -> None: + def __init__(self, identifier, parent=None, config: AdvancedConfig = None) -> None: super().__init__(parent=parent) self.setObjectName("AdvanceWidget") + self.identifier = identifier self.view = QWidget() self.cardLayout = ExpandLayout(self.view) @@ -66,6 +63,19 @@ def _initWidget(self) -> None: title=self.tr("Specifies ffmpeg path"), parent=self.view, ) + self.groupLocalTimeSwitchCard = SwitchConfigCard( + icon=FluentIcon.DATE_TIME, + title=self.tr("Local group chat time logging"), + content=self.tr("Specifies whether to enable local group chat time recording"), + parent=self.view + ) + self.groupLocalTimeListCard = TextCard( + identifier=self.identifier, + icon=FluentIcon.MENU, + title=self.tr("Swarms that need to be recorded"), + content=self.tr("Hover over for detailed tips"), + parent=self.view + ) self.debugModeCard = SwitchConfigCard( icon=FluentIcon.COMMAND_PROMPT, title=self.tr("Debug"), @@ -108,10 +118,23 @@ def _initWidget(self) -> None: parent=self.view, ) + # 当 GroupLocalTimeList 被删除至空时, 设置为 False + self.groupLocalTimeListCard.emptiedSignal.connect( + lambda: self.groupLocalTimeSwitchCard.switchButton.setChecked(False) + ) + + # 隐藏卡片,并设置条件显示 + self.groupLocalTimeListCard.hide() + self.groupLocalTimeSwitchCard.switchButton.checkedChanged.connect( + lambda checked: self.groupLocalTimeListCard.show() if checked else self.groupLocalTimeListCard.hide() + ) + self.cards = [ self.QQPathCard, self.startScriptPathCard, self.ffmpegPathCard, + self.groupLocalTimeSwitchCard, + self.groupLocalTimeListCard, self.debugModeCard, self.localFile2UrlCard, self.fileLogCard, @@ -127,6 +150,8 @@ def fillValue(self) -> None: self.QQPathCard.fillValue(self.config.QQPath) self.startScriptPathCard.fillValue(self.config.startScriptPath) self.ffmpegPathCard.fillValue(self.config.ffmpegPath) + self.groupLocalTimeSwitchCard.fillValue(self.config.GroupLocalTime.Record) + self.groupLocalTimeListCard.fillValue(self.config.GroupLocalTime.RecordList) self.debugModeCard.fillValue(self.config.debug) self.localFile2UrlCard.fillValue(self.config.localFile2url) self.fileLogCard.fillValue(self.config.fileLog) @@ -154,6 +179,10 @@ def getValue(self) -> dict: "QQPath": self.QQPathCard.getValue(), "startScriptPath": self.startScriptPathCard.getValue(), "ffmpegPath": self.ffmpegPathCard.getValue(), + "GroupLocalTime": { + "Record": self.groupLocalTimeSwitchCard.getValue(), + "RecordList": self.groupLocalTimeListCard.getValue() + }, "debug": self.debugModeCard.getValue(), "localFile2url": self.localFile2UrlCard.getValue(), "fileLog": self.fileLogCard.getValue(), diff --git a/src/Ui/AddPage/ConfigTopCard.py b/src/Ui/AddPage/ConfigTopCard.py index 8bf0815..64660a0 100644 --- a/src/Ui/AddPage/ConfigTopCard.py +++ b/src/Ui/AddPage/ConfigTopCard.py @@ -153,6 +153,9 @@ def _addBotListBtnSlot(self) -> None: with open(str(bot_config_path), "w", encoding="utf-8") as f: json.dump(bot_configs, f, indent=4) + # 同时创建bat脚本 + self._createBatScriptSlot() + # 执行刷新 it(BotListWidget).botList.updateList() diff --git a/src/Ui/AddPage/Connect.py b/src/Ui/AddPage/Connect.py index ed828f6..fb6a2f7 100644 --- a/src/Ui/AddPage/Connect.py +++ b/src/Ui/AddPage/Connect.py @@ -22,9 +22,10 @@ class ConnectWidget(ScrollArea): ## Connect Item 项对应的 QWidget """ - def __init__(self, parent=None, config: ConnectConfig = None) -> None: + def __init__(self, identifier, parent=None, config: ConnectConfig = None) -> None: super().__init__(parent=parent) self.setObjectName("ConnectWidget") + self.identifier = identifier self.view = QWidget() self.cardLayout = ExpandLayout(self) @@ -50,6 +51,7 @@ def _initWidget(self) -> None: """ self.httpConfigCard = HttpConfigCard(self.view) self.httpPostUrlCard = UrlCard( + identifier=self.identifier, icon=FluentIcon.SCROLL, title=self.tr("Http Report address"), content=self.tr("Set the address for reporting HTTP"), @@ -63,6 +65,7 @@ def _initWidget(self) -> None: parent=self.view, ) self.wsReverseUrlCard = UrlCard( + identifier=self.identifier, icon=FluentIcon.SCROLL, title=self.tr("WebSocket Reverse address"), content=self.tr("Reverse WebSocket reporting address"), diff --git a/src/Ui/BotListPage/BotList.py b/src/Ui/BotListPage/BotList.py index 8ac868e..e7758a0 100644 --- a/src/Ui/BotListPage/BotList.py +++ b/src/Ui/BotListPage/BotList.py @@ -7,7 +7,7 @@ from creart import it from qfluentwidgets import ScrollArea, FlowLayout -from src.Core.Config.ConfigModel import Config +from src.Core.Config.ConfigModel import Config, DEFAULT_CONFIG from src.Core.PathFunc import PathFunc from src.Ui.BotListPage.BotCard import BotCard @@ -99,20 +99,25 @@ def _parseList(self) -> None: # 读取配置列表 with open(str(it(PathFunc).bot_config_path), "r", encoding="utf-8") as f: bot_configs = json.load(f) - if bot_configs: - # 如果从文件加载的 bot_config 不为空则执行使用Config和列表表达式解析 - self.botList: List[Config] = [Config(**config) for config in bot_configs] - self.parent().parent().showSuccess( - title=self.tr("Load the list of bots"), - content=self.tr("The list of bots was successfully loaded"), - ) - else: + + if not bot_configs: # 创建信息条 self.parent().parent().showInfo( title=self.tr("There are no bot configuration items"), content=self.tr("You'll need to add it in the Add bot page"), ) self.botList = [] + return + + # 检查是否有新配置项并配置默认值 + bot_configs = [self.updateConfig(config, DEFAULT_CONFIG) for config in bot_configs] + + # 如果从文件加载的 bot_config 不为空则执行使用Config和列表表达式解析 + self.botList: List[Config] = [Config(**config) for config in bot_configs] + self.parent().parent().showSuccess( + title=self.tr("Load the list of bots"), + content=self.tr("The list of bots was successfully loaded"), + ) except FileNotFoundError: # 如果文件不存在则创建一个 @@ -126,3 +131,16 @@ def _parseList(self) -> None: with open(str(it(PathFunc).bot_config_path), "w", encoding="utf-8") as f: json.dump([], f, indent=4) self.botList = [] + + def updateConfig(self, user_config, default_config): + """ + ## 这是一个检查是否有新版参数并填入默认值的函数 + """ + for key, value in default_config.items(): + if isinstance(value, dict): + # 如果值是字典,则递归调用 + user_config[key] = self.updateConfig(user_config.get(key, {}), value) + else: + if key not in user_config: + user_config[key] = value + return user_config diff --git a/src/Ui/BotListPage/BotWidget/BotSetupPage.py b/src/Ui/BotListPage/BotWidget/BotSetupPage.py index 3a966fa..e34ce47 100644 --- a/src/Ui/BotListPage/BotWidget/BotSetupPage.py +++ b/src/Ui/BotListPage/BotWidget/BotSetupPage.py @@ -122,8 +122,8 @@ def _createSubPages(self) -> None: 子页面直接使用 AddWidget 中的页面 """ self.botWidget = BotWidget(self, self.config.bot) - self.connectWidget = ConnectWidget(self, self.config.connect) - self.advancedWidget = AdvancedWidget(self, self.config.advanced) + self.connectWidget = ConnectWidget("Setup", self, self.config.connect) + self.advancedWidget = AdvancedWidget("Setup", self, self.config.advanced) self.botWidget.view.setObjectName("BotListBotSetupView") self.connectWidget.view.setObjectName("BotListConnectSetupView") diff --git a/src/Ui/BotListPage/BotWidget/__init__.py b/src/Ui/BotListPage/BotWidget/__init__.py index ff077ab..bf5af52 100644 --- a/src/Ui/BotListPage/BotWidget/__init__.py +++ b/src/Ui/BotListPage/BotWidget/__init__.py @@ -7,6 +7,7 @@ from PySide6.QtGui import QTextCursor, QPixmap from PySide6.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QStackedWidget from creart import it +from loguru import logger from qfluentwidgets import ( SegmentedWidget, TransparentToolButton, FluentIcon, ToolTipFilter, PrimaryPushButton, PushButton, MessageBoxBase, SubtitleLabel, ImageLabel, ToolButton, BodyLabel @@ -285,34 +286,38 @@ def _updateButtonSlot(self) -> None: ## 更新按钮的槽函数 """ from src.Ui.BotListPage import BotListWidget + from src.Core.Config.ConfigModel import DEFAULT_CONFIG self.newConfig = Config(**self.botSetupPage.getValue()) # 读取配置列表 with open(str(it(PathFunc).bot_config_path), "r", encoding="utf-8") as f: - bot_configs = [Config(**config) for config in json.load(f)] - - if bot_configs: - # 如果从文件加载的 bot_config 不为空则进行更新(为空怎么办呢,我能怎么办,崩了呗bushi - for index, config in enumerate(bot_configs): - # 遍历配置列表,找到一样则替换 - if config.bot.QQID == self.newConfig.bot.QQID: - bot_configs[index] = self.newConfig - break - # 不可以直接使用 dict方法 转为 dict对象, 内部 WebsocketUrl 和 HttpUrl 不会自动转为 str - bot_configs = [json.loads(config.json()) for config in bot_configs] - with open(str(it(PathFunc).bot_config_path), "w", encoding="utf-8") as f: - json.dump(bot_configs, f, indent=4) - # 更新成功提示 - it(BotListWidget).showSuccess( - title=self.tr("Update success"), - content=self.tr("The updated configuration is successful") - ) - else: + bot_configs = [it(BotListWidget).botList.updateConfig(config, DEFAULT_CONFIG) for config in json.load(f)] + bot_configs = [Config(**config) for config in bot_configs] + + if not bot_configs: # 为空报错 + logger.error(f"机器人列表加载失败 数据为空: {bot_configs}") it(BotListWidget).showError( title=self.tr("Update error"), content=self.tr("Data loss within the profile") ) + return + + # 如果从文件加载的 bot_config 不为空则进行更新(为空怎么办呢,我能怎么办,崩了呗bushi + for index, config in enumerate(bot_configs): + # 遍历配置列表,找到一样则替换 + if config.bot.QQID == self.newConfig.bot.QQID: + bot_configs[index] = self.newConfig + break + # 不可以直接使用 dict方法 转为 dict对象, 内部 WebsocketUrl 和 HttpUrl 不会自动转为 str + bot_configs = [json.loads(config.json()) for config in bot_configs] + with open(str(it(PathFunc).bot_config_path), "w", encoding="utf-8") as f: + json.dump(bot_configs, f, indent=4) + # 更新成功提示 + it(BotListWidget).showSuccess( + title=self.tr("Update success"), + content=self.tr("The updated configuration is successful") + ) @Slot() def _deleteButtonSlot(self) -> None: diff --git a/src/Ui/common/InputCard/GenericCard.py b/src/Ui/common/InputCard/GenericCard.py index a72c040..605b848 100644 --- a/src/Ui/common/InputCard/GenericCard.py +++ b/src/Ui/common/InputCard/GenericCard.py @@ -49,6 +49,7 @@ def __init__( self.texts = texts or [] self.comboBox = ComboBox(self) self.comboBox.addItems(self.texts) + self.comboBox.setFixedWidth(165) self.hBoxLayout.addWidget(self.comboBox, 0, Qt.AlignmentFlag.AlignRight) self.hBoxLayout.addSpacing(16) diff --git a/src/Ui/common/InputCard/TextCard.py b/src/Ui/common/InputCard/TextCard.py new file mode 100644 index 0000000..4941691 --- /dev/null +++ b/src/Ui/common/InputCard/TextCard.py @@ -0,0 +1,215 @@ +# -*- coding: utf-8 -*- +from typing import List + +from PySide6.QtCore import Qt, Signal +from PySide6.QtWidgets import QHBoxLayout, QSizePolicy, QWidget +from creart import it +from qfluentwidgets import ( + BodyLabel, + ExpandSettingCard, + FluentIcon, + FluentIconBase, + InfoBar, + InfoBarPosition, + LineEdit, + MessageBox, + MessageBoxBase, + TitleLabel, + TransparentPushButton, + TransparentToolButton, +) + + +class TextItem(QWidget): + """ + ## Url Item + """ + + removed = Signal(QWidget) + + def __init__(self, text: str, parent=None) -> None: + """ + ## 初始化 item + + ### 参数 + - text: 传入的 text 字符串 + - parent: 父组件 + + """ + super().__init__(parent=parent) + self.text = text + self.hBoxLayout = QHBoxLayout(self) + self.urlLabel = BodyLabel(text, self) + self.removeButton = TransparentToolButton(FluentIcon.CLOSE, self) + + self.setFixedHeight(55) + self.setSizePolicy(QSizePolicy.Policy.Ignored, QSizePolicy.Policy.Fixed) + self.hBoxLayout.setContentsMargins(48, 0, 60, 0) + self.hBoxLayout.addWidget(self.urlLabel, 0, Qt.AlignmentFlag.AlignLeft) + self.hBoxLayout.addSpacing(16) + self.hBoxLayout.addStretch(1) + self.hBoxLayout.addWidget(self.removeButton, 0, Qt.AlignmentFlag.AlignRight) + self.hBoxLayout.setAlignment(Qt.AlignmentFlag.AlignVCenter) + + self.removeButton.clicked.connect(lambda: self.removed.emit(self)) + + +class TextCard(ExpandSettingCard): + """ + ## 上报 Text 列表卡片 + """ + # 成功添加 url 的信号 + addSignal = Signal() + # 当用户删除了所有 url 的信号 + emptiedSignal = Signal() + + def __init__( + self, identifier: str, icon: FluentIcon | FluentIconBase, title: str, content: str, parent=None + ) -> None: + """ + ## 初始化卡片 + + ### 参数 + - identifier: 标识符 + - icon: 卡片图标 + - title: 卡片标题 + - content: 卡片内容 + - parent: 父组件 + """ + super().__init__(icon, title, content, parent) + self.identifier = identifier + self.texts: List[str] = [] + self.textItemList: List[TextItem] = [] + + # 创建所需控件 + self.addUrlButton = TransparentPushButton(FluentIcon.ADD, self.tr("Add")) + + # 调用方法 + self._initWidget() + + def fillValue(self, values: List[str]) -> None: + self.texts = values + [self._addUrlItem(url) for url in self.texts] + + def getValue(self) -> List[str]: + return self.texts + + def clear(self) -> None: + """ + 清空卡片内容 + """ + for item in self.textItemList: + self._removeUrl(item) + self.texts.clear() + + def _initWidget(self) -> None: + """ + 设置卡片内部控件 + """ + self.addWidget(self.addUrlButton) + self.card.expandButton.setEnabled(False) + + # 初始化布局 + self.viewLayout.setSpacing(0) + self.viewLayout.setAlignment(Qt.AlignmentFlag.AlignTop) + self.viewLayout.setContentsMargins(0, 0, 0, 0) + + # 连接信号 + self.addUrlButton.clicked.connect(self._showTextInputBox) + + def _showTextInputBox(self) -> None: + """ + 显示 Text 输入框 + """ + from src.Ui.AddPage import AddWidget + from src.Ui.BotListPage.BotListWidget import BotListWidget + box = TextInputBox(it(AddWidget)) if self.identifier == "Add" else TextInputBox(it(BotListWidget)) + if not box.exec() or not box.urlLineEdit.text(): + # 如果用户取消或输入空字符,则退出函数 + return + + if box.urlLineEdit.text() in self.texts: + # 如果用户输入的值已经存在则弹出提示并退出函数 + InfoBar.error( + title=self.tr("The URL already exists"), + content=self.tr("Please enter a new URL"), + orient=Qt.Orientation.Vertical, + duration=3000, + position=InfoBarPosition.BOTTOM_RIGHT, + parent=it(AddWidget), + ) + return + + self.texts.append(box.urlLineEdit.text()) + self._addUrlItem(box.urlLineEdit.text()) + self.setExpand(True) + self.addSignal.emit() + + def _addUrlItem(self, url: str) -> None: + """ + 添加 Url Item + """ + if not self.card.expandButton.isEnabled(): + self.card.expandButton.setEnabled(True) + item = TextItem(url, self.view) + item.removed.connect(self._showConfirmDialog) + self.textItemList.append(item) + self.viewLayout.addWidget(item) + item.show() + self._adjustViewSize() + + def _showConfirmDialog(self, item: TextItem) -> None: + """ + 显示确认对话框 + """ + from src.Ui.AddPage import AddWidget + + box = MessageBox( + title=self.tr("Confirm"), + content=self.tr( + f"Are you sure you want to delete the following URLs?\n\n{item.text}" + ), + parent=it(AddWidget), + ) + box.yesSignal.connect(lambda: self._removeUrl(item)) + box.exec() + + def _removeUrl(self, item: TextItem): + """ + 移除 Url Item + """ + if item.text not in self.texts: + return + + self.texts.remove(item.text) + self.viewLayout.removeWidget(item) + item.deleteLater() + self._adjustViewSize() + + if not len(self.texts): + self.card.expandButton.clicked.emit() + self.card.expandButton.setEnabled(False) + self.emptiedSignal.emit() + + def wheelEvent(self, event) -> None: + if self.isExpand: + # 如果是展开状态则将滚轮事件向上传递 + self.parent().wheelEvent(event) + + +class TextInputBox(MessageBoxBase): + + def __init__(self, parent=None): + super().__init__(parent) + self.titleLabel = TitleLabel(self.tr("Enter"), self) + self.urlLineEdit = LineEdit() + + self.urlLineEdit.setPlaceholderText(self.tr("Enter...")) + self.urlLineEdit.setClearButtonEnabled(True) + + # 将组件添加到布局中 + self.viewLayout.addWidget(self.titleLabel) + self.viewLayout.addWidget(self.urlLineEdit) + + # 设置对话框最小宽度 + self.widget.setMinimumWidth(350) diff --git a/src/Ui/common/InputCard/UrlCard.py b/src/Ui/common/InputCard/UrlCard.py index e9fcbff..709ba66 100644 --- a/src/Ui/common/InputCard/UrlCard.py +++ b/src/Ui/common/InputCard/UrlCard.py @@ -1,10 +1,10 @@ # -*- coding: utf-8 -*- -from pydantic import HttpUrl, WebsocketUrl from typing import List, TypeVar -from creart import it from PySide6.QtCore import Qt, Signal from PySide6.QtWidgets import QHBoxLayout, QSizePolicy, QWidget +from creart import it +from pydantic import HttpUrl, WebsocketUrl from qfluentwidgets import ( BodyLabel, ExpandSettingCard, @@ -20,7 +20,6 @@ TransparentToolButton, ) - T = TypeVar("T", HttpUrl, WebsocketUrl) @@ -68,18 +67,20 @@ class UrlCard(ExpandSettingCard): emptiedSignal = Signal() def __init__( - self, icon: FluentIcon | FluentIconBase, title: str, content: str, parent=None + self, identifier: str, icon: FluentIcon | FluentIconBase, title: str, content: str, parent=None ) -> None: """ ## 初始化卡片 ### 参数 + - identifier: 标识符 - icon: 卡片图标 - title: 卡片标题 - content: 卡片内容 - parent: 父组件 """ super().__init__(icon, title, content, parent) + self.identifier = identifier self.urls: List[str] = [] self.urlItemList: List[UrlItem] = [] @@ -124,8 +125,9 @@ def _showUrlInputBox(self) -> None: 显示 URL 输入框 """ from src.Ui.AddPage import AddWidget + from src.Ui.BotListPage.BotListWidget import BotListWidget - box = UrlInputBox(it(AddWidget)) + box = UrlInputBox(it(AddWidget)) if self.identifier == "Add" else UrlInputBox(it(BotListWidget)) if not box.exec() or not box.urlLineEdit.text(): # 如果用户取消或输入空字符,则退出函数 return diff --git a/src/Ui/common/InputCard/__init__.py b/src/Ui/common/InputCard/__init__.py index 9a3ad25..14fbe81 100644 --- a/src/Ui/common/InputCard/__init__.py +++ b/src/Ui/common/InputCard/__init__.py @@ -1,8 +1,9 @@ # -*- coding: utf-8 -*- -from src.Ui.common.InputCard.HttpConfigCard import HttpConfigCard -from src.Ui.common.InputCard.UrlCard import UrlCard -from src.Ui.common.InputCard.WsConfigCard import WsConfigCard from src.Ui.common.InputCard.GenericCard import ( SwitchConfigCard, FolderConfigCard, ComboBoxConfigCard, LineEditConfigCard ) +from src.Ui.common.InputCard.HttpConfigCard import HttpConfigCard from src.Ui.common.InputCard.Item import SwitchItem, LineEditItem +from src.Ui.common.InputCard.TextCard import TextCard +from src.Ui.common.InputCard.UrlCard import UrlCard +from src.Ui.common.InputCard.WsConfigCard import WsConfigCard