紧接注册页面设计;登录页面设计也是图书管理系统其中的一个模块,模块代码结构如下:
导入的模块
import sys
from PyQt5.QtWidgets import *
import qdarkstyle
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtSql import *
import hashlib
一、类的基础设置
- 创建一个登录类,继承QWidget函数方法;设置主窗口大小、标题,调用函数setUpUI,进行主窗口布局。
class SignInWidget(QWidget):
is_admin_signal = pyqtSignal()
is_student_signal = pyqtSignal(str)
def __init__(self):
super(SignInWidget,self).__init__()
# widgit = QWidget()
# widgit.setGeometry()
self.resize(900,600)
self.setWindowTitle("欢迎使用图书管理系统")
self.setUpUI()
二、窗口布局
(一)继承垂直、水平布局函数对象
- QHBoxLayout 水平布局控件
- QVBoxLayout 垂直布局控件
- QFormLayout 表单布局控件
self.Vlayout = QVBoxLayout(self)
self.Hlayout1 = QHBoxLayout()
self.Hlayout2 = QHBoxLayout()
self.formlayout = QFormLayout()
(二)表单布局控件
1、学号和学号输入框
# 学号和输入框部件
self.label1 = QLabel("学号:") # 部件标签名
labelFont = QFont() # 部件标签字体对象
labelFont.setPixelSize(18) # 设置标签字体对象的大小
lineEditFont = QFont() # 输入框字体对象
lineEditFont.setPixelSize(16) # 设置输入框字体对象大小
self.label1.setFont(labelFont) # 绑定学号字体
# 输入框
self.lineEdit1 = QLineEdit()
self.lineEdit1.setFixedWidth(180)
self.lineEdit1.setFixedHeight(32)
self.lineEdit1.setFont(lineEditFont)
# 最多输入十个数字或字母
self.lineEdit1.setMaxLength(10)
# 将学号和输入框部件添加进表单
self.formlayout.addRow(self.label1,self.lineEdit1)
2、密码和密码输入框
# 密码
self.label2 = QLabel("密码:")
self.label2.setFont(labelFont)
# 密码输入框
self.lineEdit2 = QLineEdit()
self.lineEdit2.setFixedWidth(180)
self.lineEdit2.setFixedHeight(32)
# 密码长度
self.lineEdit2.setMaxLength(16)
3、学号和密码输入框方法设置
(1)学号输入框方法设置
- 学号输入框字符串验证
# 设置验证规则进行匹配
# 用正则传 PB[0~9]匹配0~9的数字,{8}只能匹配8个
reg = QRegExp("PB[0~9]{8}")
# QRegExpValidator 根据正则表达式检测字符串
pValidator = QRegExpValidator(self)
# 验证输入框中的数字规则
pValidator.setRegExp(reg)
# 将输入规则封装在self.lineEdit1中
self.lineEdit1.setValidator(pValidator)
(2)密码输入框方法设置
- 密码输入框字符串验证
# 设置验证规则进行匹配
# 用正则传 PB[0~9]匹配0~9的数字,{8}只能匹配8个
reg = QRegExp("PB[0~9]{8}")
# 验证输入框中的数字规则
pValidator.setRegExp(reg)
# 将输入规则封装在self.lineEdit2中
self.lineEdit2.setValidator(pValidator)
- 密码设置为不可见
# 设置密码字体大小
passwordFont = QFont()
passwordFont.setPixelSize(10)
self.lineEdit2.setFont(passwordFont)
# 设置密码为不可见
self.lineEdit2.setEchoMode(QLineEdit.Password)
# 将密码和密码输入框方法添加进表单
self.formlayout.addRow(self.label2,self.lineEdit2)
4、登录按钮标签
- 设置登录按钮大小
# 登录
self.signIn = QPushButton("登录")
self.signIn.setFixedWidth(80)
self.signIn.setFixedHeight(30)
self.signIn.setFont(labelFont)
# 将登录按钮部件添加进表单
self.formlayout.addRow("",self.signIn)
5、表单内容
- 表单(self.formlayout)
- 表单内容包含:学号和学号输入框部件、密码和密码输入框部件、登录按钮部件、学号输入框和密码输入框的字符串验证方法、密码不可见的方法。
# 将学号和输入框部件添加进表单
self.formlayout.addRow(self.label1,self.lineEdit1)
# 将密码和密码输入框部件及方法添加进表单
self.formlayout.addRow(self.label2,self.lineEdit2)
# 将登录按钮部件添加进表单
self.formlayout.addRow("",self.signIn)
(三)标题布局控件
- 添加标题界面
self.lable = QLabel("欢迎使用享学图书管理系统")
fontlable = QFont()
fontlable.setPixelSize(30)
self.lable.setFixedWidth(390)
self.lable.setFont(fontlable)
# 将标题布局控件添加在水平布局控件1内
self.Hlayout1.addWidget(self.lable,Qt.AlignCenter) # AlignCenter 对齐居中
(四)整体窗口布局
- 整体窗口布局由垂直布局展开;
- 垂直布局:水平布局控件(widget1)+ 水平布局控件(widget2)
1、widget1
- widget1=self.Hlayout1(水平布局控件1)
self.widget1 = QWidget()
self.widget1.setLayout(self.Hlayout1)
- self.Hlayout1(水平布局控件1):居中方法+标签(欢迎使用图书管理系统)
# 将标题布局控件添加在水平布局控件1内
# AlignCenter 对齐居中
self.Hlayout1.addWidget(self.lable,Qt.AlignCenter)
2、widget2
- widget2 = self.Hlayout2(水平布局控件2)
self.widget2 = QWidget()
self.widget2.setLayout(self.Hlayout2)
- self.Hlayout2 = widget3 + 居中方法
# widget3窗口 + 居中方法
self.Hlayout2.addWidget(self.widget3,Qt.AlignCenter)
- widget3 = 自身大小设置 + self.formlayout(表单控件)
self.widget3.setFixedWidth(300)
self.widget3.setFixedHeight(150)
# 将表单self.formlayout加入widget3窗口布局中
self.widget3.setLayout(self.formlayout)
- self.formlayout = 部件和方法(学号和学号输入框部件、密码和密码输入框部件、登录按钮部件、学号输入框和密码输入框的字符串验证方法、密码不可见的方法)
- 详细代码见上5.表单内容。
3、窗口布局示例
三、身份验证
(一)发送信号
- 绑定登录按钮
self.signIn.clicked.connect(self.signInCheck)
self.lineEdit2.returnPressed.connect(self.signInCheck)
self.lineEdit1.returnPressed.connect(self.signInCheck)
(二)接收信号
- 定义新函数
- 接收输入框内容
def signInCheck(self):
studentId = self.lineEdit1.text()
password = self.lineEdit2.text()
(三)逻辑判断
1、判断输入框内容是否为空。
- 若为空执行if语句。
if (studentId == "" or password == ""):
print(QMessageBox.warning(self,"警告","学号和密码不可为空!",QMessageBox.Yes,QMessageBox.Yes))
return
- 不为空执行以下语句。
2、连接数据库。
- 查询账号
db = QSqlDatabase.addDatabase("QSQLITE")
db.setDatabaseName('./db/LibraryManagement.db')
db.open()
query = QSqlQuery()
sql = "SELECT * FROM user WHERE StudentId='%s'" % (studentId)
query.exec_(sql)
db.close()
- 密码加密保存
hl = hashlib.md5()
hl.update(password.encode(encoding="utf-8"))
3、判断账号是否存在。
- 如果不存在,执行if语句,弹出消息提示框。
if (not query.next()):
print(QMessageBox.information(self, "提示","该账号不存在!", QMessageBox.Yes,QMessageBox.Yes))
- 如果存在,执行以下语句。
4、验证账号密码。
- 若存在,执行else语句,验证账号密码是否成功。
else:
# 验证账号密码
if (studentId == query.value(0) and hl.hexdigest() == query.value(2)):
- 若验证账号密码成功。就检查账号属性为管理员账号还是学生账号。
# 对比管理员信息,如果索引值3为1,跳转到管理员界面
if (query.value(3)==1):
- 若验证账号密码不成功,就弹出提示框。
# 验证密码失败,进行提示。
else:
print(QMessageBox.information(self, "提示", "密码错误!", QMessageBox.Yes,QMessageBox.Yes))
return
- 若检查账号属性为管理员账号,执行调用管理员后台窗口界面的语句。
# 对比管理员信息,如果索引值3为1,跳转到管理员界面
if (query.value(3)==1):
self.is_admin_signal.emit()
- 若检查账号不是管理员账号,执行调用学生窗口界面语句。
# 其他的跳转的学生界面
else:
self.is_student_signal.emit(studentId)
四、程序入口运行
if __name__ == '__main__':
app = QApplication(sys.argv)
app.setWindowIcon(QIcon("./"))
app.setStyleSheet(qdarkstyle.load_stylesheet_pyqt5())
mainMindow = SignInWidget()
mainMindow.show()
sys.exit(app.exec_())
五、完整代码
import sys
from PyQt5.QtWidgets import *
import qdarkstyle
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtSql import *
import hashlib
class SignInWidget(QWidget):
is_admin_signal = pyqtSignal()
is_student_signal = pyqtSignal(str)
def __init__(self):
super(SignInWidget,self).__init__()
# widgit = QWidget()
# widgit.setGeometry()
self.resize(900,600)
self.setWindowTitle("欢迎使用图书管理系统")
self.setUpUI()
def setUpUI(self):
self.Vlayout = QVBoxLayout(self)
self.Hlayout1 = QHBoxLayout()
self.Hlayout2 = QHBoxLayout()
self.formlayout = QFormLayout()
# 学号的标签和输入框
self.label1 = QLabel("学号:") # 标签名
labelFont = QFont() # 标签字体对象
labelFont.setPixelSize(18) # 设置标签字体对象的大小
lineEditFont = QFont() # 输入框字体对象
lineEditFont.setPixelSize(16) # 设置输入框字体对象大小
self.label1.setFont(labelFont) # 绑定学号字体
# 输入框
self.lineEdit1 = QLineEdit()
self.lineEdit1.setFixedWidth(180)
self.lineEdit1.setFixedHeight(32)
self.lineEdit1.setFont(lineEditFont)
# 最多输入十个数字或字母
self.lineEdit1.setMaxLength(10)
# 标签和输入框通过表单 addRow
self.formlayout.addRow(self.label1,self.lineEdit1)
# 密码
self.label2 = QLabel("密码:")
self.label2.setFont(labelFont)
self.lineEdit2 = QLineEdit()
self.lineEdit2.setFixedWidth(180)
self.lineEdit2.setFixedHeight(32)
self.lineEdit2.setMaxLength(16)
# 设置验证进行匹配
# 用正则传 PB[0~9]匹配0~9的数字,{8}只能匹配8个
# 学号输入框字符串验证
reg = QRegExp("PB[0~9]{8}")
# QRegExpValidator 根据正则表达式检测字符串
pValidator = QRegExpValidator(self)
pValidator.setRegExp(reg)
self.lineEdit1.setValidator(pValidator)
# passwordFont = QFont()
# 密码输入框字符串验证
reg = QRegExp("[a-zA-Z0-9]+$")
# pValidator = QRegExpValidator(self)
pValidator.setRegExp(reg)
self.lineEdit2.setValidator(pValidator)
passwordFont = QFont()
passwordFont.setPixelSize(10)
self.lineEdit2.setFont(passwordFont)
# 设置密码为不可见
self.lineEdit2.setEchoMode(QLineEdit.Password)
self.formlayout.addRow(self.label2,self.lineEdit2)
# 登录
self.signIn = QPushButton("登录")
self.signIn.setFixedWidth(80)
self.signIn.setFixedHeight(30)
self.signIn.setFont(labelFont)
self.formlayout.addRow("",self.signIn)
# 添加标题界面
self.lable = QLabel("欢迎使用享学图书管理系统")
fontlable = QFont()
fontlable.setPixelSize(30)
self.lable.setFixedWidth(390)
self.lable.setFont(fontlable)
# 将标题布局控件添加在水平布局控件1内
self.Hlayout1.addWidget(self.lable,Qt.AlignCenter) # AlignCenter 对齐居中
# 整体的布局
# QWidget 窗口控件 一个程序拥有一个窗口或多个窗口
# 每个窗口都有很多个控件
# 所有的窗口都是直接或简介的继承自QWidget
self.widget1 = QWidget()
self.widget1.setLayout(self.Hlayout1)
self.widget3 = QWidget()
self.widget3.setFixedWidth(300)
self.widget3.setFixedHeight(150)
self.widget3.setLayout(self.formlayout)
self.Hlayout2.addWidget(self.widget3,Qt.AlignCenter)
self.widget2 = QWidget()
self.widget2.setLayout(self.Hlayout2)
self.Vlayout.addWidget(self.widget1)
self.Vlayout.addWidget(self.widget2,Qt.AlignTop)
self.signIn.clicked.connect(self.signInCheck)
self.lineEdit2.returnPressed.connect(self.signInCheck)
self.lineEdit1.returnPressed.connect(self.signInCheck)
def signInCheck(self):
studentId = self.lineEdit1.text()
password = self.lineEdit2.text()
if (studentId == "" or password == ""):
print(QMessageBox.warning(self,"警告","学号和密码不可为空!",QMessageBox.Yes,QMessageBox.Yes))
return
# 打开数据库链接
db = QSqlDatabase.addDatabase("QSQLITE")
db.setDatabaseName('./db/LibraryManagement.db')
db.open()
query = QSqlQuery()
sql = "SELECT * FROM user WHERE StudentId='%s'" % (studentId)
query.exec_(sql)
db.close()
hl = hashlib.md5()
hl.update(password.encode(encoding="utf-8"))
if (not query.next()):
print(QMessageBox.information(self, "提示","该账号不存在!", QMessageBox.Yes,QMessageBox.Yes))
# 如果账号存在
else:
# 验证账号密码
if (studentId == query.value(0) and hl.hexdigest() == query.value(2)):
# 对比管理员信息,如果索引值3为1,跳转到管理员界面
if (query.value(3)==1):
self.is_admin_signal.emit()
# 其他的跳转的学生界面
else:
self.is_student_signal.emit(studentId)
# 验证密码失败,进行提示。
else:
print(QMessageBox.information(self, "提示", "密码错误!", QMessageBox.Yes,QMessageBox.Yes))
return
if __name__ == '__main__':
app = QApplication(sys.argv)
app.setWindowIcon(QIcon("./"))
app.setStyleSheet(qdarkstyle.load_stylesheet_pyqt5())
mainMindow = SignInWidget()
mainMindow.show()
sys.exit(app.exec_())
待后续....