import string import sys from PySide6.QtCore import Signal from PySide6.QtGui import Qt from PySide6.QtWidgets import QLabel, QFrame, QPushButton, QVBoxLayout, QHBoxLayout, QApplication from app.common.Manager import UserManager from qfluentwidgets import FluentStyleSheet, PrimaryPushButton, TextWrap, LineEdit, InfoBar, InfoBarPosition, ComboBox from qfluentwidgets.components.dialog_box.dialog import Ui_MessageBox from qframelesswindow import FramelessDialog class AddUserInstance: yesSignal = Signal() cancelSignal = Signal() def __init__(self, *args, **kwargs): pass def _setUpUi(self, title, parent): self.titleLabel = QLabel(title, parent) self.user = LineEdit() self.userBox = QHBoxLayout() self.user_text = QLabel('用户ID', parent) self.userBox.addWidget(self.user_text) self.userBox.addWidget(self.user) self.userPassword = LineEdit() self.userPasswordBox = QHBoxLayout() self.userPassword_text = QLabel('用户密码', parent) self.userPasswordBox.addWidget(self.userPassword_text) self.userPasswordBox.addWidget(self.userPassword) self.userPermissionBox = QHBoxLayout() self.userPermission_text = QLabel('用户权限', parent) self.userPermission = ComboBox(self) self.userPermission.addItem('管理员') self.userPermission.addItem('用户') self.userPermissionBox.addWidget(self.userPermission_text) self.userPermissionBox.addWidget(self.userPermission) self.buttonGroup = QFrame(parent) self.yesButton = PrimaryPushButton(self.tr('OK'), self.buttonGroup) self.cancelButton = QPushButton(self.tr('Cancel'), self.buttonGroup) self.vBoxLayout = QVBoxLayout(parent) self.textLayout = QVBoxLayout() self.buttonLayout = QHBoxLayout(self.buttonGroup) self.__initWidget() def __initWidget(self): self.__setQss() self.__initLayout() # fixes https://github.com/zhiyiYo/PyQt-Fluent-Widgets/issues/19 self.yesButton.setAttribute(Qt.WA_LayoutUsesWidgetRect) self.cancelButton.setAttribute(Qt.WA_LayoutUsesWidgetRect) self.yesButton.setFocus() self.buttonGroup.setFixedHeight(81) self._adjustText() #self.yesButton.clicked.connect(self.__onYesButtonClicked) self.cancelButton.clicked.connect(self.__onCancelButtonClicked) def _adjustText(self): if self.isWindow(): if self.parent(): w = max(self.titleLabel.width(), self.parent().width()) chars = max(min(w / 9, 140), 30) else: chars = 100 else: w = max(self.titleLabel.width(), self.window().width()) chars = max(min(w / 9, 100), 30) #self.contentLabel.setText(TextWrap.wrap(self.content, chars, False)[0]) def __initLayout(self): self.vBoxLayout.setSpacing(0) self.vBoxLayout.setContentsMargins(0, 0, 0, 0) self.vBoxLayout.addLayout(self.textLayout, 1) self.vBoxLayout.addLayout(self.userBox) self.vBoxLayout.addLayout(self.userPasswordBox) self.vBoxLayout.addLayout(self.userPermissionBox) self.vBoxLayout.addWidget(self.buttonGroup, 0, Qt.AlignBottom) self.vBoxLayout.setSizeConstraint(QVBoxLayout.SetMinimumSize) self.textLayout.setSpacing(12) self.textLayout.setContentsMargins(24, 24, 24, 24) self.textLayout.addWidget(self.titleLabel, 0, Qt.AlignTop) self.userBox.setContentsMargins(24, 24, 24, 24) self.userPasswordBox.setContentsMargins(24, 24, 24, 24) self.userPermissionBox.setContentsMargins(24, 24, 24, 24) self.buttonLayout.setSpacing(12) self.buttonLayout.setContentsMargins(24, 24, 24, 24) self.buttonLayout.addWidget(self.yesButton, 1, Qt.AlignVCenter) self.buttonLayout.addWidget(self.cancelButton, 1, Qt.AlignVCenter) def __onCancelButtonClicked(self): self.reject() self.cancelSignal.emit() def __onYesButtonClicked(self): self.accept() self.yesSignal.emit() def __setQss(self): self.titleLabel.setObjectName("titleLabel") self.buttonGroup.setObjectName('buttonGroup') self.cancelButton.setObjectName('cancelButton') FluentStyleSheet.DIALOG.apply(self) self.yesButton.adjustSize() self.cancelButton.adjustSize() class AddUserDialog(FramelessDialog, AddUserInstance): yesSignal = Signal() cancelSignal = Signal() def __init__(self, parent=None): super().__init__(parent=parent) self._setUpUi("人员登记", self) self.windowTitleLabel = QLabel("人员登记", self) self.setResizeEnabled(False) self.resize(540, 192) self.titleBar.hide() self.vBoxLayout.insertWidget(0, self.windowTitleLabel, 0, Qt.AlignTop) self.windowTitleLabel.setObjectName('windowTitleLabel') FluentStyleSheet.DIALOG.apply(self) self.setFixedSize(self.size()) self.yesButton.clicked.connect(self.createUser) def setTitleBarVisible(self, isVisible: bool): self.windowTitleLabel.setVisible(isVisible) def createUser(self): user = self.user.text() password = self.userPassword.text() permission = None if self.userPermission.text() == '管理员': permission = 'Admin' else: permission = 'User' if user == '' or password == '' or permission == '': InfoBar.error( title='数据缺失', content="请检查您填写的数据是否完整", orient=Qt.Horizontal, isClosable=True, position=InfoBarPosition.BOTTOM_RIGHT, duration=-1, # won't disappear automatically parent=self ) elif not self.validate_password(password): InfoBar.warning( title='密码简单', content="您的密码过于简单, 请重新输入并包含至少一个小写字母、一个大写字母、一个数字和一个特殊字符!", orient=Qt.Horizontal, isClosable=False, # disable close button position=InfoBarPosition.TOP_LEFT, duration=2000, parent=self ) else: UserManager.addUser(user, password, permission) InfoBar.success( title='用户添加成功', content="你已经成功添加了用户 "+ user + " 您可以进行操作或退出", orient=Qt.Horizontal, isClosable=True, position=InfoBarPosition.TOP, duration=2000, parent=self ) def validate_password(self, password): """Validate a password with common requirements.""" errors = [] # Check password length if len(password) < 8: errors.append("Password must be at least 8 characters.") # Check for lowercase letter if not any(char in string.ascii_lowercase for char in password): errors.append("Password must contain at least one lowercase letter.") # Check for uppercase letter if not any(char in string.ascii_uppercase for char in password): errors.append("Password must contain at least one uppercase letter.") # Check for digit if not any(char.isdigit() for char in password): errors.append("Password must contain at least one digit.") # Check for special character special_characters = string.punctuation if not any(char in special_characters for char in password): errors.append("Password must contain at least one special character.") # If no errors, the password is valid if not errors: return True, "Password is valid." # If there are errors, the password is invalid else: return False, errors