# coding:utf-8 from PyQt6.QtCore import Qt from PyQt6.QtGui import QPixmap from PyQt6.QtWidgets import QFileDialog, QHBoxLayout, QLabel, QVBoxLayout, QWidget from qfluentwidgets import ( AvatarWidget, BodyLabel, GroupHeaderCardWidget, HyperlinkLabel, InfoBarPosition, LineEdit, PushButton, ScrollArea, Slider, SubtitleLabel, VerticalSeparator, ) from qfluentwidgets import InfoBar, MessageBoxBase from app.core import cfg, lang, qconfig, signalBus, UserAvatarUpdateThread, userConfig, UserNickNameUpdateThread from app.view.widgets.custom_background_messageBox import CustomBgMessageBox class NickNameEdit(MessageBoxBase): def __init__(self, parent=None): super().__init__(parent) self.titleLabel = SubtitleLabel(lang("修改昵称"), self) self.lineEdit = LineEdit(self) self.widget.setMinimumWidth(200) self.viewLayout.addWidget( self.titleLabel, 0, Qt.AlignmentFlag.AlignTop | Qt.AlignmentFlag.AlignLeft ) self.viewLayout.addWidget(self.lineEdit) self.yesButton.setText("确定") self.cancelButton.setText("取消") class BasicInformationSettingCard(GroupHeaderCardWidget): def __init__(self, parent=None): super().__init__(parent) self.setObjectName("basicInformationSettingCard") self.setTitle(lang("用户信息")) self.nickNameEdit = PushButton(lang("修改昵称"), self) self.nickNameEdit.clicked.connect(self._changeNickName) self.addGroup(":app/icons/Nickname.svg", userConfig.userId, "UID", QLabel(self)) self.addGroup( ":app/icons/Nickname.svg", userConfig.userName, lang("用户昵称"), self.nickNameEdit, ) self.addGroup( ":app/icons/Email.svg", userConfig.userEmail, lang("电子邮箱"), QLabel(self), ) self.addGroup( ":app/icons/Group.svg", userConfig.userGroup, lang("当前用户组"), QLabel(self), ) self.addGroup( ":app/icons/Score.svg", userConfig.userScore, "积分", QLabel(self) ) self.addGroup( ":app/icons/Date.svg", userConfig.userCreatedTime, lang("用户注册时间"), QLabel(self), ) def _changeNickName(self): w = NickNameEdit(self.window()) def _onNickNameSuccess(): self.groupWidgets[2].setTitle(newNickName) InfoBar.success( lang("修改成功"), lang("昵称修改成功"), Qt.Orientation.Horizontal, True, 1000, InfoBarPosition.TOP_RIGHT, self.window(), ) def _onNickNameError(error): InfoBar.error( lang("修改失败"), error, Qt.Orientation.Horizontal, True, 1000, InfoBarPosition.TOP_RIGHT, self.window(), ) if w.exec(): newNickName = w.lineEdit.text() self.nickNameServiceThread = UserNickNameUpdateThread(newNickName) self.nickNameServiceThread.successUpdate.connect(_onNickNameSuccess) self.nickNameServiceThread.errorUpdate.connect(_onNickNameError) self.nickNameServiceThread.start() class SoftWardSettingWidget(GroupHeaderCardWidget): def __init__(self, parent=None): super().__init__(parent) self.setTitle("软件设置") self.downloadSavePathButton = PushButton(lang("选择保存路径"), self) self.downloadSavePathButton.clicked.connect(self._chooseDownloadSavePath) self.addGroup( ":app/icons/SavePath.svg", qconfig.get(cfg.downloadSavePath), lang("选择下载保存路径"), self.downloadSavePathButton, ) def _chooseDownloadSavePath(self): folder_path = QFileDialog.getExistingDirectory(self, lang("选择文件夹")) if folder_path: print(f"选择的文件夹路径是: {folder_path}") qconfig.set(cfg.downloadSavePath, folder_path) self.groupWidgets[0].setTitle(folder_path) InfoBar.success( lang("修改成功"), lang("下载保存路径修改成功"), Qt.Orientation.Horizontal, True, 1000, InfoBarPosition.TOP_RIGHT, self.window(), ) class ThemeSettingWidget(GroupHeaderCardWidget): def __init__(self, parent=None): super().__init__(parent) self.setTitle(lang("背景图片设置")) self.officialBackgroundButton = PushButton(lang("官方背景图"), self) self.officialBackgroundButton.clicked.connect(self.officialBackground) self.customBackgroundButton = PushButton(lang("选择自定义背景"), self) self.customBackgroundButton.clicked.connect(self.customBackground) self.opacitySlider = Slider(Qt.Orientation.Horizontal, self) self.opacitySlider.setRange(0, 10) self.opacitySlider.setFixedWidth(100) self.opacitySlider.setValue(int(qconfig.get(cfg.customOpactity) * 10)) self.opacitySlider.valueChanged.connect(self.setOpacity) self.addGroup( ":app/icons/BgImage.svg", lang("官方预设背景图片"), lang("选择背景图片"), self.officialBackgroundButton, ) self.addGroup( ":app/icons/BgImage.svg", lang("自定义背景图片"), lang("选择自定义图片,选择后请不要更改图片位置"), self.customBackgroundButton, ) self.addGroup( ":app/icons/Opacity.svg", lang("图片背景透明度"), lang("设置图片背景透明度"), self.opacitySlider, ) def officialBackground(self): w = CustomBgMessageBox(self.window()) if w.exec(): index = w.returnImage() qconfig.set(cfg.customBackground, f"app\\resource\\images\\bg{index}.png") signalBus.backgroundChanged.emit() def customBackground(self): file_name, _ = QFileDialog.getOpenFileName( self, "选择背景", "", "Image Files (*.png *.jpg *.jpeg *.bmp);;All Files (*)", ) qconfig.set(cfg.customBackground, file_name) signalBus.backgroundChanged.emit() def setOpacity(self, opacity): qconfig.set(cfg.customOpactity, opacity / 10) signalBus.opacityChanged.emit() class AgreementLabelWidget(QWidget): def __init__(self, parent=None): super().__init__(parent) self.hBoxLayout = QHBoxLayout(self) self.hBoxLayout.setAlignment(Qt.AlignmentFlag.AlignCenter) self.privacyPolicy = HyperlinkLabel( lang("隐私协议"), self, ) self.userAgreement = HyperlinkLabel( lang("用户协议"), self, ) self.verticalSeparator = VerticalSeparator(self) self.verticalSeparator.setFixedHeight(15) self.privacyPolicy.setUrl("https://mp.miaostars.com/ysxy") self.userAgreement.setUrl("https://mp.miaostars.com/xy") self.hBoxLayout.addWidget(self.privacyPolicy, 0, Qt.AlignmentFlag.AlignCenter) self.hBoxLayout.addSpacing(10) self.hBoxLayout.addWidget(self.verticalSeparator) self.hBoxLayout.addSpacing(10) self.hBoxLayout.addWidget( self.userAgreement, ) class SettingInterface(ScrollArea): """Setting interface""" def __init__(self, parent=None): super().__init__(parent=parent) self.scrollWidget = QWidget() self.expandLayout = QVBoxLayout(self.scrollWidget) self.avatarWidget = AvatarWidget(self.scrollWidget) self.basicInformationSettingCard = BasicInformationSettingCard( self.scrollWidget ) self.softWardSettingWidget = SoftWardSettingWidget(self.scrollWidget) self.themeSettingWidget = ThemeSettingWidget(self.scrollWidget) self.agreementLabelWidget = AgreementLabelWidget(self.scrollWidget) self.infoLabel = BodyLabel( "增值电信业务经营许可证:B1-20191399鄂ICP备2025132158号 \n ©2025 LeonPan \n 武汉喵星创想互联网科技有限公司", self.scrollWidget, ) self.__initWidget() def __initWidget(self): self.resize(1000, 800) self.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff) # self.setViewportMargins(0, 100, 0, 20) self.setWidget(self.scrollWidget) self.setWidgetResizable(True) self.setObjectName("settingInterface") self.scrollWidget.setObjectName("scrollWidget") self.scrollWidget.setStyleSheet("background:transparent;border:none;") self.setStyleSheet("background:transparent;border:none;") self.avatarWidget.setImage(QPixmap(":app/images/logo.png")) # Connect click event to open file dialog for avatar selection self.avatarWidget.clicked.connect(self._openAvatarDialog) self.infoLabel.setAlignment(Qt.AlignmentFlag.AlignCenter) self.infoLabel.setStyleSheet("color:gray;font-size:12px;") # initialize layout self.__initLayout() self._connectSignalToSlot() def __initLayout(self): # add setting card group to layout # self.expandLayout.setSpacing(28) self.expandLayout.addWidget( self.avatarWidget, 0, Qt.AlignmentFlag.AlignTop | Qt.AlignmentFlag.AlignHCenter, ) self.expandLayout.addWidget( self.basicInformationSettingCard, 0, Qt.AlignmentFlag.AlignTop ) self.expandLayout.addWidget( self.softWardSettingWidget, 0, Qt.AlignmentFlag.AlignTop ) self.expandLayout.addWidget( self.themeSettingWidget, 0, Qt.AlignmentFlag.AlignTop ) self.expandLayout.addWidget( self.agreementLabelWidget, 1, Qt.AlignmentFlag.AlignBottom ) self.expandLayout.addSpacing(5) self.expandLayout.addWidget(self.infoLabel, 0, Qt.AlignmentFlag.AlignBottom) def _connectSignalToSlot(self): ... def _openAvatarDialog(self): """Open file dialog to select avatar image""" fileDialog = QFileDialog(self) fileDialog.setWindowTitle(lang("选择图片")) fileDialog.setAcceptMode(QFileDialog.AcceptMode.AcceptOpen) fileDialog.setFileMode(QFileDialog.FileMode.ExistingFile) fileDialog.setNameFilter("图片文件 (*.png *.jpg *.jpeg *.bmp)") if fileDialog.exec(): file_path = fileDialog.selectedFiles()[0] try: image = QImage(file_path) if not image.isNull(): self.changeAvatar(image) # Update the avatar widget with the new image self.avatarWidget.setImage(QPixmap.fromImage(image)) except Exception as e: InfoBar.error( lang("选择失败"), str(e), Qt.Orientation.Horizontal, True, 1000, InfoBarPosition.TOP_RIGHT, self.window(), ) def updateAvatar(self, avatarPixmap): self.avatarWidget.setImage(avatarPixmap) def changeAvatar(self, image): def avatarUpdateError(error): InfoBar.error( lang("修改失败"), error, Qt.Orientation.Horizontal, True, 1000, InfoBarPosition.TOP_RIGHT, self.window(), ) self.avatarWidget.setEnabled(True) def avatarUpdateSuccess(): InfoBar.success( lang("修改成功"), lang("头像修改成功"), Qt.Orientation.Horizontal, True, 1000, InfoBarPosition.TOP_RIGHT, self.window(), ) self.avatarWidget.setEnabled(True) self.avatarUpdateThread = UserAvatarUpdateThread(image) self.avatarUpdateThread.successUpdate.connect(avatarUpdateSuccess) self.avatarUpdateThread.errorUpdate.connect(avatarUpdateError) self.avatarUpdateThread.start() self.avatarWidget.setEnabled(False)