为 PyQt5 登录页,添加登录逻辑代码,实现登录与退出
使用 PyQt5(PySide2)+SQLAlchemy 做一个登录注册页(四)
本文将介绍自己用 PyQt5+SQLAlchemy 做的一个登录注册页,使用邮箱接收验证码,本文介绍是前后端未分离的实现方式,后续将出一个前后端分离的,你可以将 PyQt5 改为 PySide2 以获得更宽松的开源协议
本文由于涉及到的代码较多,将会是一个系列,会有多篇文章
系列文章索引
- 设计登录注册页面
- 添加代码运行登录注册页,并为其添加一些样式,和调用资源文件
- 使用 SQLAlchemy 实现用户数据库管理
- 为登录页,添加登录逻辑代码,实现登录与退出
- 给注册页,添加注册逻辑代码,实现用户的注册验证
- 给忘记密码页,添加逻辑,实现密码找回
- 给登录添加记住用户密码功能,并优化一些内容
必要说明
- 使用的环境
requirements.txt
# Python3.8.10 x32
# Windows10 x64
PyQt5
pyqt5-tools
PyMySQL~=1.1.0
sqlalchemy~=2.0.25
bcrypt~=4.1.2
email-validator # new add
- 项目结构(显示变化的部分)
--- QtLoginRegistration
|--- lib
|--- __init__.py
|--- basic_function.py # 存放公共方法
|--- crud
|--- __init__.py
|--- crud.py # 数据库操作
|--- requirements.txt # 添加 email-validator
为登录页,添加登录逻辑代码,实现登录与退出
第1步
添加必填校验
- 新建
lib/basic_function.py
文件,保存基础公共方法,增加以下内容
#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
"""
@ Project : QtLoginRegistration
@ File : basic_function.py
@ Author : yqbao
@ Version : V1.0.0
@ Description : 基础公共方法类
"""
from PyQt5.QtCore import QObject
from PyQt5.QtGui import QIcon, QPixmap
from PyQt5.QtWidgets import QMessageBox
class BasicFunction(QObject):
"""一个基础公共方法类"""
def __init__(self, parent=None):
super().__init__(parent=parent)
@staticmethod
def info_message(msg):
"""公共的消息提示"""
message = QMessageBox(QMessageBox.Information, "提示", msg, QMessageBox.Yes)
icon = QIcon()
icon.addPixmap(QPixmap(":/home/images/testing_x48.ico"), QIcon.Normal, QIcon.Off)
message.setWindowIcon(icon)
message.button(QMessageBox.Yes).setText('确定')
message.exec() # 模态显示
- 在
core/login_register.py
中添加如下代码 GitHub完整代码
# 导入
from lib.basic_function import BasicFunction
# 在 构造方法 __init__ 中实例公共方法类
self.basic_function = BasicFunction(self)
# 在 init_ui 方法中 添加登录页需要绑定的信号
self.pushButtonLogin.clicked.connect(self.login)
# 在类中添加 2个新方法
def login(self):
"""登录动作"""
if not self.login_required(): # 必填校验未通过
return
def login_required(self):
"""登录必填校验"""
self.account = self.lineEditUsername.text()
self.password = self.lineEditPassword.text()
if not self.account.strip():
self.basic_function.info_message("用户账号不能为空")
return
if not self.password.strip():
self.basic_function.info_message("用户密码不能为空")
return
return True
- 运行效果
第2步
完善登录校验逻辑
- 新建
crud/crud.py
文件,实现数据库操作,增加以下内容
#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
"""
@ Project : QtLoginRegistration
@ File : crud.py
@ Author : yqbao
@ Version : V1.0.0
@ Description : 数据库操作
"""
from typing import Union
from sqlalchemy import and_
from sqlalchemy.orm import Session
from db import models
class CRUD(object):
@staticmethod
def _commit(db: Session, db_obj):
try:
db.commit()
return db_obj
except Exception:
db.rollback()
return
class CRUDUser(CRUD):
@staticmethod
def get_user_by_email(db: Session, email: str) -> Union[models.User, None]:
"""根据email查询用户"""
return db.query(models.User).filter(and_(models.User.email == email, models.User.deleted == 0)).first()
@staticmethod
def get_user_by_username(db: Session, username: str) -> Union[models.User, None]:
"""根据username查询用户"""
return db.query(models.User).filter(and_(models.User.username == username, models.User.deleted == 0)).first()
- 在
core/login_register.py
中添加如下代码 GitHub完整代码
# 导入
import bcrypt
from email_validator import validate_email, EmailNotValidError
from crud.crud import CRUDUser
from db import session_factory
# 在 构造方法 __init__ 中实例数据库操作类
self.user = CRUDUser()
# 修改 login 方法
def login(self):
"""登录动作"""
if not self.login_required(): # 必填校验未通过
return
try:
info = validate_email(self.account, check_deliverability=False)
email = info.normalized
with session_factory() as db:
user = self.user.get_user_by_email(db, email)
except EmailNotValidError: # 输入的是否是邮箱,不是将报错
with session_factory() as db:
user = self.user.get_user_by_username(db, self.account)
if not user: # 查询空,无此用户
self.basic_function.info_message("用户名或密码错误")
return
if not user.disabled:
self.basic_function.info_message("此用户账号已被禁用")
return
bytes_my_password = bytes(self.password, encoding="utf-8")
str_my_hash_password = user.password
bytes_my_hash_password = bytes(str_my_hash_password, encoding='utf-8')
check = bcrypt.checkpw(bytes_my_password, bytes_my_hash_password)
if not check: # 校验通过,设置QDialog对象状态为允许
self.basic_function.info_message("用户名或密码错误")
return
self.accept()
- 运行效果
第3步
修改main_window.py
实现用户退出
#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
"""
@ Project : QtLoginRegistration
@ File : main_window.py
@ Author : yqbao
@ Version : V1.0.0
@ Description :
"""
from PyQt5.QtCore import QFile
from PyQt5.QtWidgets import QWidget, QDialog
from core.login_register import UiLoginRegisterQDialog
from uis.MianWindow import Ui_MainWindow
class MainWindow(QWidget, Ui_MainWindow):
"""界面逻辑"""
def __init__(self, parent=None):
super().__init__(parent=parent)
self.setupUi(self)
self.pushButton.clicked.connect(self.logout)
def logout(self):
"""退出"""
self.hide()
login_register_ui = UiLoginRegisterQDialog() # 设置登录
qss = QFile(':/QSS/qss/login_register.qss') # 资源使用 QFile 打开
if qss.open(QFile.ReadOnly | QFile.Text):
style_bytearray = qss.readAll() # 类型为 QByteArray
style = str(style_bytearray, encoding='UTF-8')
login_register_ui.setStyleSheet(style)
qss.close()
if login_register_ui.exec() == QDialog.Accepted:
login_register_ui.close()
self.show()
本文来自博客园作者:星尘的博客,转载请注明出处:https://www.cnblogs.com/yqbaowo/p/18002723