使用Qt的PySide2制作了一款用户登录界面,特点如下:
- 使用Qt的PySide2构建GUI界面;
- 加密方式:md5加salt方式进行两次加密,提高密码强度;
- 对登录/注册逻辑进行梳理;
- PySide2实现窗口间互相调用。
话不多说直接上代码:
#!/usr/bin/env python3.7
# -*- coding: utf-8 -*-
from PySide2 import QtCore, QtGui, QtWidgets
import sys, time, os
import hashlib
import re
from mainwindow import MainWindow
class welcomWidget(QtWidgets.QMainWindow):
def __init__(self):
self.userFile = os.path.join(sys.path[0],"user.txt")
super(welcomWidget, self).__init__()
# 设定登录页面大小
self.resize(800, 480)
self.centralwidget = QtWidgets.QWidget(self)
self.setCentralWidget(self.centralwidget)
self.setWindowTitle('注册登录界面')
# 添加组控件(位置大小基于centralwidget)
self.groupBox = QtWidgets.QGroupBox(self.centralwidget)
self.groupBox.setGeometry(QtCore.QRect(50, 25, 700, 160))
self.groupBox.setTitle("用户注册/登录")
self.groupBox.setStyleSheet("QGroupBox{font-family:'黑体';font-size:14px;}")
# 设置用户名label(位置大小基于groupBox)
self.nameLabel = QtWidgets.QLabel(self.groupBox)
self.nameLabel.setGeometry(QtCore.QRect(50, 35, 130, 30))
self.nameLabel.setText("用户名称:")
self.nameLabel.setStyleSheet("QLabel{font-family:'黑体';font-size:24px;}")
self.nameLabel.setAlignment(QtCore.Qt.AlignCenter)
# 设置密码label(位置大小基于groupBox)
self.pwdLabel = QtWidgets.QLabel(self.groupBox)
self.pwdLabel.setGeometry(QtCore.QRect(50, 105, 130, 30))
self.pwdLabel.setText("用户密码:")
self.pwdLabel.setStyleSheet("QLabel{font-family:'黑体';font-size:24px;}")
self.pwdLabel.setAlignment(QtCore.Qt.AlignCenter)
# 设置图片区域(位置大小基于groupBox)
self.picLabel = QtWidgets.QLabel(self.groupBox)
self.pic=QtGui.QPixmap(os.path.join(sys.path[0],'pictures/welcome.png'))
self.picLabel.setPixmap(self.pic)
self.picLabel.setGeometry(QtCore.QRect(440, 22, 210, 120))
# 设置用户名输入框(位置大小基于groupBox)
self.userLineedit = QtWidgets.QLineEdit(self.groupBox)
self.userLineedit.setGeometry(QtCore.QRect(170, 35, 200, 30))
self.userLineedit.setPlaceholderText('请输入用户名')
self.userLineedit.setStyleSheet("QLineEdit{font-family:'黑体';font-size:16px;}")
self.userLineedit.setClearButtonEnabled(True)
# 设置密码输入框(位置大小基于groupBox)
self.pwdLineedit = QtWidgets.QLineEdit(self.groupBox)
self.pwdLineedit.setGeometry(QtCore.QRect(170, 105, 200, 30))
self.pwdLineedit.setPlaceholderText('请输入密码')
self.pwdLineedit.setStyleSheet("QLineEdit{font-family:'黑体';font-size:16px;}")
self.pwdLineedit.setClearButtonEnabled(True)
# 设置登录按钮(位置大小基于centralwidget)
self.loginButton = QtWidgets.QPushButton(self.centralwidget)
self.loginButton.setGeometry(QtCore.QRect(50, 200, 200, 40))
self.loginButton.setText('登录系统')
self.loginButton.setShortcut('Enter')
self.loginButton.setStyleSheet("QPushButton{font-family:'黑体';font-size:16px;}")
# 设置注册按钮(位置大小基于centralwidget)
self.registerButton = QtWidgets.QPushButton(self.centralwidget)
self.registerButton.setGeometry(QtCore.QRect(300, 200, 200, 40))
self.registerButton.setText('新用户注册')
self.registerButton.setShortcut('Enter')
self.registerButton.setStyleSheet("QPushButton{font-family:'黑体';font-size:16px;}")
# 设置退出按钮(位置大小基于centralwidget)
self.cancelButton = QtWidgets.QPushButton(self.centralwidget)
self.cancelButton.setGeometry(QtCore.QRect(551, 200, 200, 40))
self.cancelButton.setText('退出系统')
self.cancelButton.setShortcut('Escape')
self.cancelButton.setStyleSheet("QPushButton{font-family:'黑体';font-size:16px;}")
# 以下均为设置label填写文字内容(位置大小基于centralwidget)
self.contactLabel = QtWidgets.QLabel(self.centralwidget)
self.contactLabel.setGeometry(QtCore.QRect(50, 250, 700, 20))
self.contactLabel.setText('用户名为数字及(或)大写字母及(或)小写字母,长度须大于等于4字节。')
self.contactLabel.setStyleSheet("QLabel{font-family:'黑体';font-size:16px; color:red;}")
self.contactLabel.setAlignment(QtCore.Qt.AlignCenter)
self.warningLabel = QtWidgets.QLabel(self.centralwidget)
self.warningLabel.setGeometry(QtCore.QRect(50, 280, 700, 20))
self.warningLabel.setText("密码为数字、大写字母、小写字母,且至少含大小写字母及数字各1个,长度须大于等于6字节。")
self.warningLabel.setStyleSheet("QLabel{font-family:'黑体';font-size:16px; line-height:100px; color:red;}")
self.warningLabel.setAlignment(QtCore.Qt.AlignCenter)
self.warningLabel = QtWidgets.QLabel(self.centralwidget)
self.warningLabel.setGeometry(QtCore.QRect(50, 310, 700, 20))
self.warningLabel.setText("用户名密码储存于user.txt文件,使用hashlib加salt方式两次加密,强度满足需求。")
self.warningLabel.setStyleSheet("QLabel{font-family:'黑体';font-size:16px; line-height:100px; color:red;}")
self.warningLabel.setAlignment(QtCore.Qt.AlignCenter)
# 设置LCD钟表(位置大小基于centralwidget)
self.dateclockLCD=QtWidgets.QLCDNumber(self.centralwidget)
self.dateclockLCD.setDigitCount(19)
self.dateclockLCD.setStyleSheet("border:0px; color: black; background: rgb(240, 240, 240);")
self.dateclockLCD.resize(400,150)
self.dateclockLCD.setSegmentStyle(QtWidgets.QLCDNumber.Flat)
self.dateclockLCD.setGeometry(QtCore.QRect(50,355,700,100))
self.timeTimer = QtCore.QTimer()
self.timeTimer.connect(self.timeTimer, QtCore.SIGNAL('timeout()'), self.showTime)
self.timeTimer.start(1000)
# 禁止窗口最大最小化
self.setWindowFlags(QtCore.Qt.WindowCloseButtonHint)
# 禁止拉伸窗口
self.setFixedSize(self.width(), self.height())
# 密码隐藏
self.pwdLineedit.setEchoMode(QtWidgets.QLineEdit.Password)
# 点击取消按钮退出应用
self.connect(self.cancelButton, QtCore.SIGNAL('clicked()'), self.closeWelcome)
# 点击确定按钮进入主窗口
self.loginButton.clicked.connect(self.login)
# 点击注册按钮进行注册
self.registerButton.clicked.connect(self.register)
# 按规则检查用户名:4字符及以上,且仅包括数字及(或)大小写字母
def username_check(self, username):
if len(username)>=4:
if re.match("^[A-Za-z0-9]+$", username)==None:
QtWidgets.QMessageBox.information(self, u'用户名不符合要求', u'用户名仅包括数字及大小写字母,请检查后重新输入', QtWidgets.QMessageBox.Ok)
return False
else:
return True
else:
QtWidgets.QMessageBox.information(self, u'用户名不符合要求', u'用户名须大于4字符,请检查后重新输入', QtWidgets.QMessageBox.Ok)
return False
# 按规则检查密码:6字符及以上,且仅包括数字及大小写字母,至少含大小写字母及数字各1个
def password_check(self,password):
if len(password)>=6:
if re.match("^(?:(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])).*$", password)==None:
QtWidgets.QMessageBox.information(self, u'密码不符合要求', u'密码仅包括数字及大小写字母,且至少含大小写字母及数字各1个,请检查后重新输入', QtWidgets.QMessageBox.Ok)
return False
else:
return True
else:
QtWidgets.QMessageBox.information(self, u'密码不符合要求', u'密码须大于6字符,请检查后重新输入', QtWidgets.QMessageBox.Ok)
return False
# 用户名密码加salt加密
def encryption(self,info):
# 加salt(002587字符串)
md5=hashlib.md5(b'002587')
md5.update(info.encode('utf-8'))
return md5.hexdigest()
# 检查用户名是否已存在
def user_exist(self,username):
try:
with open(self.userFile,"r",encoding="utf-8") as f:
for line in f:
line = line.strip()
line_new = line.split("#")
if line_new[0] == username:
return True
return False
except IOError:
QtWidgets.QMessageBox.warning(self, u'系统错误', u'系统错误程序即将关闭,\n请稍后重启程序或联系管理员', QtWidgets.QMessageBox.Ok)
if QtWidgets.QMessageBox.Ok:
self.closeWelcome()
return False
# 验证及登录
def login(self):
username=self.userLineedit.text()
password=self.pwdLineedit.text()
if username=='':
QtWidgets.QMessageBox.information(self, u'用户名为空', u'请输入用户名', QtWidgets.QMessageBox.Ok)
elif password=='':
QtWidgets.QMessageBox.information(self, u'密码为空', u'请输入密码', QtWidgets.QMessageBox.Ok)
else:
# 用户名密码两次加密提高强度
username1=self.encryption(username)
username2=self.encryption(username1)
username=username2
password1=self.encryption(password)
password2=self.encryption(password1)
password=password2
if self.user_exist(username):
try:
with open(self.userFile,"r",encoding="utf-8") as f:
for line in f:
line = line.strip()
line_list = line.split("#")
if line_list[0] == username and line_list[1] == password:
self.homePage = MainWindow()
self.homePage.show()
self.hide()
elif line_list[0] == username and line_list[1] != password:
QtWidgets.QMessageBox.information(self, u'提示', u'密码或错误,请重新输入', QtWidgets.QMessageBox.Ok)
if QtWidgets.QMessageBox.Ok:
self.userLineedit.setText('')
self.pwdLineedit.setText('')
except IOError:
QtWidgets.QMessageBox.warning(self, u'系统错误', u'系统错误程序即将关闭,\n请稍后重启程序或联系管理员', QtWidgets.QMessageBox.Ok)
if QtWidgets.QMessageBox.Ok:
self.closeWelcome()
else:
no_user=QtWidgets.QMessageBox.question(self, u'用户不存在', u'当前用户不存在,是否注册新用户?')
if no_user==QtWidgets.QMessageBox.StandardButton.Yes:
self.register()
if no_user==QtWidgets.QMessageBox.StandardButton.No:
self.userLineedit.setText('')
self.pwdLineedit.setText('')
# 验证及注册
def register(self):
username=self.userLineedit.text()
password=self.pwdLineedit.text()
if self.username_check(username) and self.password_check(password):
username1=self.encryption(username)
username2=self.encryption(username1)
username=username2
if not self.user_exist(username):
password1=self.encryption(password)
password2=self.encryption(password1)
password=password2
with open(self.userFile,"a",encoding="utf-8")as f:
temp = "\n" + username + "#" + password
f.write(temp)
register_success=QtWidgets.QMessageBox.question(self, u'提示', u'注册成功,是否登录?')
if register_success==QtWidgets.QMessageBox.StandardButton.Yes:
self.login()
if register_success==QtWidgets.QMessageBox.StandardButton.No:
self.userLineedit.setText('')
self.pwdLineedit.setText('')
else:
QtWidgets.QMessageBox.information(self, u'提示', u'用户名已存在,请重新输入', QtWidgets.QMessageBox.Ok)
if QtWidgets.QMessageBox.Ok:
self.userLineedit.setText('')
self.pwdLineedit.setText('')
else:
self.userLineedit.setText('')
self.pwdLineedit.setText('')
# 配合LCD显示时间
def showTime(self):
mytime = time.strftime('%Y-%m-%d %H:%M:%S')
self.dateclockLCD.display(mytime)
# 关闭窗口
def closeWelcome(self):
self.close()
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
gui = welcomWidget()
gui.show()
sys.exit(app.exec_())
待完善项目:
- user.txt文件保护及定时备份;
- 多次用户名密码错误锁定/删除功能;
- 用户注销功能;
- 不同用户分区读取文件功能;
- 密码找回功能(利用注册时提供的唯一识别码);
- 其他。