Files
Projects/toolbox/codes/ui/login_ui.py
2025-10-10 17:16:08 +08:00

259 lines
11 KiB
Python

import sys
from PySide6.QtWidgets import QApplication, QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QLabel, QTabWidget, QLineEdit, QMessageBox, QSizePolicy
from PySide6.QtCore import Qt, QSize
from PySide6.QtGui import QFont, QIcon, QPixmap, QShortcut
from codes.common import clibs, db_operation
from codes.common.secure_encrypt import PassCipher
from codes.ui import main_ui
from codes.common.exception_handler import handle_exception
class LoginWindow(QWidget):
def __init__(self):
super().__init__()
self.pre_do()
self.init_ui()
self.post_do()
def pre_do(self):
db_operation.db_init()
db_operation.db_conn()
def init_ui(self):
self.setObjectName("LoginWindow")
self.setMinimumSize(420, 200)
self.setMaximumSize(500, 240)
self.resize(480, 200)
self.setWindowTitle("登录")
self.setWindowIcon(QIcon(clibs.icon))
self.setFont(QFont("Consolas", 14))
self.layout_outer = QHBoxLayout()
self.lb_logo = QLabel()
self.lb_logo.setObjectName("lb_logo")
self.lb_logo.setAlignment(Qt.AlignmentFlag.AlignCenter)
self.lb_logo.setSizePolicy(QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Preferred)
self.lb_logo.setPixmap(QPixmap(clibs.logo))
self.lb_logo.setFixedSize(QSize(120, 120))
self.lb_logo.setScaledContents(True)
self.layout_outer.addWidget(self.lb_logo)
self.tabW_login = QTabWidget()
self.tabW_login.setObjectName("tabW_login")
self.tab_login = QWidget()
self.tab_login.setObjectName("tab_login")
self.tabW_login.addTab(self.tab_login, "登录")
self.tab_register = QWidget()
self.tab_register.setObjectName("tab_register")
self.tabW_login.addTab(self.tab_register, "注册")
self.layout_outer.addWidget(self.tabW_login)
# 登陆页面
self.layout_H_username = QHBoxLayout()
self.lb_username = QLabel("账号")
self.lb_username.setObjectName("lb_username")
self.lb_username.setAlignment(Qt.AlignmentFlag.AlignCenter)
self.layout_H_username.addWidget(self.lb_username)
self.le_username = QLineEdit()
self.le_username.setObjectName("le_username")
self.le_username.setFocus()
self.layout_H_username.addWidget(self.le_username)
self.layout_H_password = QHBoxLayout()
self.lb_password = QLabel("密码")
self.lb_password.setObjectName("lb_password")
self.lb_password.setAlignment(Qt.AlignmentFlag.AlignCenter)
self.layout_H_password.addWidget(self.lb_password)
self.le_password = QLineEdit()
self.le_password.setObjectName("le_password")
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.setObjectName("btn_login")
self.btn_login.setAutoDefault(True)
self.btn_cancel = QPushButton("取消")
self.btn_cancel.setObjectName("btn_cancel")
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.setObjectName("lb_username_reg")
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.setObjectName("le_username_reg")
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.setObjectName("lb_password_reg")
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.setObjectName("le_password_reg")
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.setObjectName("lb_password_reg_confirm")
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.setObjectName("le_password_reg")
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.setObjectName("btn_login_reg")
self.btn_login_reg.setAutoDefault(True)
self.btn_cancel_reg = QPushButton("取消")
self.btn_cancel_reg.setObjectName("btn_cancel_reg")
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_outer)
self.le_username.setFocus()
def post_do(self):
self.setup_slot()
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)
self.le_password.returnPressed.connect(self.login_check)
self.le_password_reg_confirm.returnPressed.connect(self.register_check)
QShortcut("Esc", self).activated.connect(self.close)
QShortcut("Alt+1", self).activated.connect(lambda: self.tabW_login.setCurrentIndex(0))
QShortcut("Alt+2", self).activated.connect(lambda: self.tabW_login.setCurrentIndex(1))
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()
@handle_exception()
def login_check(self):
def login_failed(flag: int = 0):
reason = {-1: "用户名或密码为空", 0: "用户名未注册", 1: "解密成功,密码错误", 2: "解密失败,密码错误", 3: "数据库中有重复的用户名"}
self.le_username.clear()
self.le_password.clear()
self.le_username.setFocus()
QMessageBox.critical(self, "错误", "账号或密码错误,请重新输入!")
raise Exception(f"username:{username} login failed, reason: {reason[flag]}")
def validate_login():
nonlocal username, password
record = db_operation.db_query_users(username)
if username == "" or password == "":
login_failed(flag=-1)
if len(record) == 0:
login_failed(flag=0)
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)
try:
decrypt_password = cipher.decrypt(login_info["password"])
if password != decrypt_password:
login_failed(flag=1)
else:
self.mainWindow = main_ui.MainWindow()
self.mainWindow.show()
clibs.username = username
clibs.password = password
db_operation.db_write_logs(f"username:{username} 登录成功!")
self.deleteLater()
except ValueError:
login_failed(flag=2)
else:
login_failed(flag=3)
username = self.le_username.text()
password = self.le_password.text()
validate_login()
@handle_exception()
def register_check(self):
def register_failed(flag: int = 0):
reason = {-1: "用户名或密码为空", 0: "两次密码不一致", 1: "密码长度不合规", 2: "用户名已存在", 3: "数据库中有重复的用户名"}
self.le_username_reg.clear()
self.le_password_reg.clear()
self.le_password_reg_confirm.clear()
self.le_username_reg.setFocus()
QMessageBox.critical(self, "错误", "账号错误,密码长度(>8)不合规,或两次输入密码不一致,请确认后重新输入!")
raise Exception(f"register failed, reason: {reason[flag]}")
def validate_register():
nonlocal username, password, password_confirm
record = db_operation.db_query_users(username)
if username == "" or password == "" or password_confirm == "":
register_failed(flag=-1)
if password != password_confirm:
register_failed(flag=0)
if len(password) < clibs.config["minimum_password_length"]:
register_failed(flag=1)
if len(record) == 0:
salt = PassCipher.gen_salt("@".join([username, password]))
cipher = PassCipher(salt)
password_encrypted = cipher.encrypt(password)
db_operation.db_write_users(username, password_encrypted, salt)
QMessageBox.information(self, "成功", "注册成功,切换至登录窗口进行登录!")
self.tabW_login.setCurrentIndex(self.tabW_login.indexOf(self.tab_login))
elif len(record) == 1:
register_failed(flag=2)
else:
register_failed(flag=3)
username = self.le_username_reg.text()
password = self.le_password_reg.text()
password_confirm = self.le_password_reg_confirm.text()
validate_register()
def closeEvent(self, event):
event.accept()
if __name__ == '__main__':
app = QApplication(sys.argv)
window = LoginWindow()
window.show()
sys.exit(app.exec())