为 PyQt5 登录页,添加登录逻辑代码,实现登录与退出

使用 PyQt5(PySide2)+SQLAlchemy 做一个登录注册页(四)

本文将介绍自己用 PyQt5+SQLAlchemy 做的一个登录注册页,使用邮箱接收验证码本文介绍是前后端未分离的实现方式,后续将出一个前后端分离的,你可以将 PyQt5 改为 PySide2 以获得更宽松的开源协议

本文由于涉及到的代码较多,将会是一个系列,会有多篇文章

系列文章索引

  1. 设计登录注册页面
  2. 添加代码运行登录注册页,并为其添加一些样式,和调用资源文件
  3. 使用 SQLAlchemy 实现用户数据库管理
  4. 为登录页,添加登录逻辑代码,实现登录与退出
  5. 给注册页,添加注册逻辑代码,实现用户的注册验证
  6. 给忘记密码页,添加逻辑,实现密码找回
  7. 给登录添加记住用户密码功能,并优化一些内容

必要说明

  • 使用的环境 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步

添加必填校验

  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()  # 模态显示

  1. 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
  1. 运行效果

image


第2步

完善登录校验逻辑

  1. 新建 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()

  1. 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()
  1. 运行效果

image
image


第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()

GitHub完整代码
本文章的原文地址
GitHub主页

posted @ 2024-02-02 14:55  星尘的博客  阅读(305)  评论(0编辑  收藏  举报