import sys from PySide6.QtWidgets import QApplication, QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QLabel, QTabWidget, QListWidget, QStackedWidget, QCheckBox, QSpinBox, QToolBox, QLineEdit, QTableWidget, QTreeWidget, QCalendarWidget, QMessageBox, QToolBar, QSizePolicy from PySide6.QtCore import Qt, QTime, QSize, QRect,QEvent, QThread from PySide6.QtGui import QCursor, QFont, QIcon, QImage, QPixmap, QShortcut from codes.common import clibs, db_operation from codes.common.secure_encrypt import PassCipher from codes.ui import main_ui class LoginWindow(QWidget): def __init__(self): super().__init__() self.init_ui() self.setup_slot() self.predos() self.le_username.setFocus() def init_ui(self): self.setMinimumSize(420, 200) self.setMaximumSize(500, 240) self.resize(480, 200) self.setWindowTitle("登录") self.setWindowIcon(QIcon(f"{clibs.base_path}/assets/media/icon.ico")) self.setFont(QFont("Consolas", 14)) self.layout_outter = QHBoxLayout() self.lb_logo = QLabel() self.lb_logo.setAlignment(Qt.AlignmentFlag.AlignCenter) self.lb_logo.setSizePolicy(QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Preferred) self.lb_logo.setPixmap(QPixmap(f"{clibs.base_path}/assets/media/logo.png")) self.lb_logo.setFixedSize(QSize(120, 120)) self.lb_logo.setScaledContents(True) self.layout_outter.addWidget(self.lb_logo) self.tabW_login = QTabWidget() self.tab_login = QWidget() self.tabW_login.addTab(self.tab_login, "登录") self.tab_register = QWidget() self.tabW_login.addTab(self.tab_register, "注册") self.layout_outter.addWidget(self.tabW_login) # 登陆页面 self.layout_H_username = QHBoxLayout() self.lb_username = QLabel("账号") self.lb_username.setAlignment(Qt.AlignmentFlag.AlignCenter) self.layout_H_username.addWidget(self.lb_username) self.le_username = QLineEdit() self.le_username.setFocus() self.layout_H_username.addWidget(self.le_username) self.layout_H_password = QHBoxLayout() self.lb_password = QLabel("密码") self.lb_password.setAlignment(Qt.AlignmentFlag.AlignCenter) self.layout_H_password.addWidget(self.lb_password) self.le_password = QLineEdit() self.le_password.setEchoMode(QLineEdit.EchoMode.Password) self.layout_H_password.addWidget(self.le_password) self.layout_H_button = QHBoxLayout() self.btn_login = QPushButton("登录") self.btn_login.setAutoDefault(True) self.btn_cancel = QPushButton("取消") self.btn_cancel.setAutoDefault(True) self.layout_H_button.addWidget(self.btn_login) self.layout_H_button.addWidget(self.btn_cancel) self.layout_V_user_pass = QVBoxLayout() self.layout_V_user_pass.addLayout(self.layout_H_username) self.layout_V_user_pass.addLayout(self.layout_H_password) self.layout_V_user_pass.addLayout(self.layout_H_button) self.tab_login.setLayout(self.layout_V_user_pass) # 注册页面 self.layout_H_username_reg = QHBoxLayout() self.lb_username_reg = QLabel("账号设定") self.lb_username_reg.setAlignment(Qt.AlignmentFlag.AlignCenter) self.layout_H_username_reg.addWidget(self.lb_username_reg) self.le_username_reg = QLineEdit() self.le_username_reg.setFocus() self.layout_H_username_reg.addWidget(self.le_username_reg) self.layout_H_password_reg = QHBoxLayout() self.lb_password_reg = QLabel("密码设定") self.lb_password_reg.setAlignment(Qt.AlignmentFlag.AlignCenter) self.layout_H_password_reg.addWidget(self.lb_password_reg) self.le_password_reg = QLineEdit() self.le_password_reg.setEchoMode(QLineEdit.EchoMode.Password) self.layout_H_password_reg.addWidget(self.le_password_reg) self.layout_H_password_reg_confirm = QHBoxLayout() self.lb_password_reg_confirm = QLabel("密码确认") self.lb_password_reg_confirm.setAlignment(Qt.AlignmentFlag.AlignCenter) self.layout_H_password_reg_confirm.addWidget(self.lb_password_reg_confirm) self.le_password_reg_confirm = QLineEdit() self.le_password_reg_confirm.setEchoMode(QLineEdit.EchoMode.Password) self.layout_H_password_reg_confirm.addWidget(self.le_password_reg_confirm) self.layout_H_button_reg = QHBoxLayout() self.btn_login_reg = QPushButton("确认") self.btn_login_reg.setAutoDefault(True) self.btn_cancel_reg = QPushButton("取消") self.btn_cancel_reg.setAutoDefault(True) self.layout_H_button_reg.addWidget(self.btn_login_reg) self.layout_H_button_reg.addWidget(self.btn_cancel_reg) self.layout_V_user_pass_reg = QVBoxLayout() self.layout_V_user_pass_reg.addLayout(self.layout_H_username_reg) self.layout_V_user_pass_reg.addLayout(self.layout_H_password_reg) self.layout_V_user_pass_reg.addLayout(self.layout_H_password_reg_confirm) self.layout_V_user_pass_reg.addLayout(self.layout_H_button_reg) self.tab_register.setLayout(self.layout_V_user_pass_reg) self.setLayout(self.layout_outter) def setup_slot(self): self.tabW_login.currentChanged.connect(self.onChange_tabW) self.btn_login.clicked.connect(self.login_check) self.btn_cancel.clicked.connect(self.close) self.btn_login_reg.clicked.connect(self.register_check) self.btn_cancel_reg.clicked.connect(self.close) QShortcut("Esc", self).activated.connect(self.close) self.le_password.returnPressed.connect(self.login_check) self.le_password_reg_confirm.returnPressed.connect(self.register_check) def predos(self): db_file = clibs.base_path / "assets/database/toolbox.db" if not db_file.exists(): db_operation.db_init(db_file) def onChange_tabW(self): text = self.tabW_login.tabText(self.tabW_login.currentIndex()) if text == "登录": self.le_username.clear() self.le_password.clear() self.le_username.setFocus() elif text == "注册": self.le_username_reg.clear() self.le_password_reg.clear() self.le_password_reg_confirm.clear() self.le_username_reg.setFocus() else: raise Exception(f"Unknown TabWidget Name: {text}") def login_check(self): def login_failed(): self.le_username.clear() self.le_password.clear() self.le_username.setFocus() QMessageBox.critical(self, "错误", "账号或密码错误,请重新输入!") def validate_login(): nonlocal username, password conn, cursor = db_operation.db_conn() cursor.execute(f""" SELECT * FROM users where username = "{username}" """) record = cursor.fetchall() if len(record) == 0: login_failed() elif len(record) == 1: keys = ["id", "timestamp", "username", "password", "salt"] login_info = dict(zip(keys, record[0])) salt = PassCipher.gen_salt("@".join([username, password])) cipher = PassCipher(salt) # password_encrypt = cipher.encrypt("@".join([username, password])) # print(f"password_encrypt = {password_encrypt}") # exit() try: decrypt_password = cipher.decrypt(login_info["password"]) if password != decrypt_password: login_failed() return False else: self.mainWindow = main_ui.MainWindow() self.mainWindow.show() db_operation.db_close(conn, cursor) clibs.username = username clibs.password = password self.close() return True except ValueError: login_failed() return False else: raise Exception(f"username duplicated: {username}") username = self.le_username.text() password = self.le_password.text() validate_login() def register_check(self): def register_failed(flag: int = 0): self.le_username_reg.clear() self.le_password_reg.clear() self.le_password_reg_confirm.clear() self.le_username_reg.setFocus() if flag == 0: QMessageBox.critical(self, "错误", "账号已存在,或两次输入密码不一致,请重新输入!") elif flag == 1: QMessageBox.critical(self, "错误", "密码长度不符合要求,请重新输入!") def validate_register(): nonlocal username, password, password_confirm, record, conn, cursor if password != password_confirm: register_failed() return False if len(password) < clibs.account["minimum_password_length"]: register_failed(flag=1) return False if len(record) == 0: salt = PassCipher.gen_salt("@".join([username, password])) cipher = PassCipher(salt) password_encrypted = cipher.encrypt(password) cursor.execute("INSERT INTO users (username, password, salt) VALUES (?, ?, ?)", (username, password_encrypted, salt)) QMessageBox.information(self, "成功", "注册成功,切换至登录窗口进行登录!") self.tabW_login.setCurrentIndex(self.tabW_login.indexOf(self.tab_login)) return True elif len(record) == 1: register_failed() return False else: raise Exception(f"username duplicated: {username}") username = self.le_username_reg.text() password = self.le_password_reg.text() password_confirm = self.le_password_reg_confirm.text() conn, cursor = db_operation.db_conn() cursor.execute(f""" SELECT * FROM users where username = "{username}" """) record = cursor.fetchall() validate_register() if __name__ == '__main__': app = QApplication(sys.argv) window = LoginWindow() window.show() sys.exit(app.exec())