364 lines
12 KiB
Python
364 lines
12 KiB
Python
|
|
# 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)
|