PySide2制作登录界面(含密码加密)

使用Qt的PySide2制作了一款用户登录界面,特点如下:

  1. 使用Qt的PySide2构建GUI界面;
  2. 加密方式:md5加salt方式进行两次加密,提高密码强度;
  3. 对登录/注册逻辑进行梳理;
  4. 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_())

待完善项目:

  1. user.txt文件保护及定时备份;
  2. 多次用户名密码错误锁定/删除功能;
  3. 用户注销功能;
  4. 不同用户分区读取文件功能;
  5. 密码找回功能(利用注册时提供的唯一识别码);
  6. 其他。

猜你喜欢

转载自blog.csdn.net/m0_37728676/article/details/110821654
今日推荐