Files
Projects/toolbox/codes/ui/login_ui.py

245 lines
11 KiB
Python

import sys
from pathlib import Path
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):
self.m = Path(__file__).stem
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(exception: bool = False):
self.le_username.clear()
self.le_password.clear()
self.le_username.setFocus()
if not exception:
QMessageBox.critical(self, "错误", "账号或密码错误,请重新输入!")
else:
QMessageBox.critical(self, "错误", "账号重复,需检查数据库,更正后再尝试登录!")
def validate_login():
nonlocal username, password
clibs.conn, clibs.cursor = db_operation.db_conn()
record = db_operation.db_query_users(username)
if len(record) == 0:
login_failed()
return False
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()
return False
else:
self.mainWindow = main_ui.MainWindow()
self.mainWindow.show()
db_operation.db_close()
clibs.username = username
clibs.password = password
self.close()
return True
except ValueError:
login_failed()
return False
else:
db_operation.db_write_logs(f"username duplicated: {username}", self.m, "error")
login_failed(exception=True)
return False
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, "错误", "密码长度不符合要求,请重新输入!")
elif flag == 2:
QMessageBox.critical(self, "错误", "账号重复,需检查数据库,更正后再尝试登录!")
def validate_register():
nonlocal username, password, password_confirm
clibs.conn, clibs.cursor = db_operation.db_conn()
record = db_operation.db_query_users(username)
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)
db_operation.db_write_users(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:
db_operation.db_write_logs(f"username duplicated: {username}", self.m, "error")
register_failed(flag=2)
return False
username = self.le_username_reg.text()
password = self.le_password_reg.text()
password_confirm = self.le_password_reg_confirm.text()
validate_register()
if __name__ == '__main__':
app = QApplication(sys.argv)
window = LoginWindow()
window.show()
sys.exit(app.exec())