这是个学生成绩信息系统的窗口化,结合了sqlite3。
刚写好登录注册窗口,会陆续更新。
窗口设计用的是Qtdesinger,可参考:记录分享学习Qt设计师的文章及简介
1、能在出错的时候在注册页面显示错误信息,Label处的字体会变化,且标红;
2、账号输入框后有一个图标(action)能进行判断;
3、在注册成功的时候能创建一个独属于他的数据库。
(1)传统的登录界面和注册界面;
(2)在注册窗口能进行各种限定,比如账号和密码的限定长度,以及验证两次密码的一致(后来美化了消息提示,用了四个用于提示的标签);
(3)注册成功将往账号数据库里面添加这个账号的信息,并创建一个独属于这个账号的数据库;
(4)在账号窗口能进行验证账号的正确性;
(5)连接两个窗口的相互跳转:
①登录窗口能打开注册窗口,此时登录窗口 不 自动关闭;
②注册成功后 自动关闭 注册窗口,回到登录窗口,即使之前关掉了登录窗口,重新打开即可。
(1)一个数据库用来存放系统的账号密码和用户名信息;
(2)一个账号注册成功就多一个独属于它的数据库,存放学生成绩信息。
import sqlite3
(1)创建系统账号的数据库
def create_account_db( db_name):
"""创建系统账号的数据库"""
cn = sqlite3.connect( db_name)
c = cn.cursor()
sql = '''CREATE TABLE Accounts(
Account CHAR(15) PRIMARY KEY,
Aname CHAR(4) NOT NULL,
Password CHAR(15) NOT NULL
);'''
c.execute(sql)
cn.commit()
cn.close()
(2)创建学生信息的数据库
def create_stu_db( db_name):
"""创建学生信息的数据库"""
cn = sqlite3.connect( db_name)
c = cn.cursor()
sql = '''CREATE TABLE Students(
Sno CHAR(10) PRIMARY KEY,
Sname NVARCHAR(4) NOT NULL,
Sgender NCHAR(1)
CHECK( Sgender='男' or Sgender='女')
default '男',
Sbirth TEXT,
Sclass NVARCHAR(8),
Snative NVARCHAR(20)
);'''#学生表
c.execute(sql)
sql = '''CREATE TABLE Courses(
Cno CHAR(8) PRIMARY KEY,
Cname NVARCHAR(20) NOT NULL,
Chours INTEGER,
Ccredit INTEGER
);'''#课程表
c.execute(sql)
sql = '''CREATE TABLE Reports(
Sno CHAR(10),
Cno CHAR(8),
Racademicyear INT,
Rterm INT,
Grade INT,
PRIMARY KEY (Sno, Cno)
);'''#成绩表
c.execute(sql)
cn.commit()
cn.close()
窗口设计用的是Qtdesinger,可参考:记录分享学习Qt设计师的文章及简介
用ui文件转换成py文件,再修了一下。为了节省文章长度就不列出,如果需要的话,可以直接下载,上传了资源,各需要2积分。
下载注册窗口的:PyQt5学生成绩信息系统(一):注册窗口-signup.py
下载登录窗口的:PyQt5学生成绩信息系统(一):登录窗口-signin.py
import sys
import os
import sqlite3 #用于数据库
from PyQt5.QtWidgets import QApplication, QWidget, QMessageBox, QAction, QLineEdit
from PyQt5.QtCore import QRegExp
from PyQt5.QtGui import QRegExpValidator,QIcon
from usemainwindow import * #用于登录窗口的登录按钮后调用系统主窗口,后面文章会用到这个文件
from signup import * #导入注册的视图代码
from signin import * #导入登录的视图代码
将数据从sql格式转换成 列表 镶嵌 字典 的格式并返回。
超级好用的一个函数,经常被我用于提取数据库里面的信息。
def common( cn, sql):
"""将数据从sql格式转换成列表镶嵌字典的格式并返回"""
cursor = cn.execute(sql)
information = []
for row in cursor:
information.append( row)
return information
判断账号是否已经存在:
①在注册时如果已经存在就不能重复;
②在登录时如果不存在要进行提示。
在登录时要判断账号和密码是否匹配。
db_name_account = "stugrade.db" #系统账号信息存放的数据库
def judge_account( account):
"""用于判断账号是否存在"""
cn = sqlite3.connect(db_name_account)
sql = '''SELECT DISTINCT Account
FROM Accounts
'''
aaccounts = common(cn, sql)
for acc in aaccounts:
if acc[0] == account:
return 1 #返回1说明账号存在
return 0
def judge_ac_and_pw( account, password):
"""用于判断账号和密码是否匹配"""
cn = sqlite3.connect(db_name_account)
sql = '''SELECT DISTINCT Account, Password
FROM Accounts
'''
acpws = common(cn, sql)
for acpw in acpws:
if acpw[0] == account and acpw[1] == password:
return 1 #返回1说明账号和密码存在
return 0
class FormSignUp(QWidget, Ui_SignUp):
①调用视图代码;
② self.lineEdit_name.editingFinished.connect(self.confirm_name):
当用户名的输入框结束编辑时会发出信号连接 confirm_name();
③ all_validator() 是使用了正则表达式,限制账号和用户名只能输入数字和密码;
④action 是为了给账号的输入框加上 “√” 的验证按钮,点击这个按钮后会连接 action_confirm_account()
def __init__(self, parent=None):
super(FormSignUp, self).__init__(parent)
self.setupUi(self)
self.lineEdit_name.editingFinished.connect(self.confirm_name)
self.all_validator() # 正则表达式不能和editingFinished()一起用
action = QAction(self) # 给账号加√按钮
action.setIcon(QIcon("../pyfile/check.png"))
action.triggered.connect(self.action_confirm_account)
self.lineEdit_account.addAction(action, QLineEdit.TrailingPosition)
限制账号和用户名只能输入数字和密码。
验证器不能和 editingFinished() 一起使用,即不能在使用验证器的同时,在结束输入的时候 自动连接 验证的函数。
def all_validator(self): #账号和密码的正则表达式
regx = QRegExp("^[0-9A-Za-z]{14}$")
validator1 = QRegExpValidator(regx, self.lineEdit_account)
self.lineEdit_account.setValidator(validator1)
validator2 = QRegExpValidator(regx, self.lineEdit_password)
self.lineEdit_password.setValidator(validator2)
validator3 = QRegExpValidator(regx, self.lineEdit_confirmpassword)
self.lineEdit_confirmpassword.setValidator(validator3)
不限制用户名的命名格式,就只限制了“不能为空”,当为空的时候会弹出警告的消息窗口,并在提示的标签改变文字并标红。
① self.tip_name.setText(“建议为姓名”):
setText() 能改变标签显示的信息
② self.tip_name.setStyleSheet(“color:black;”):
setStyleSheet 能改变文字的样式颜色,"color:red;"能把颜色变红,同理可证。
def confirm_name(self):
"""确认用户名是否为正确格式"""
self.tip_name.setText("建议为姓名")
self.tip_name.setStyleSheet("color:black;")
self.name_count = 0
name = self.lineEdit_name.text()
if len(name) == 0:
QMessageBox.warning(self, "警告", "用户名为空")
self.tip_name.setText("用户名为空")
self.tip_name.setStyleSheet("color:red;") #把标签信息修改为红色
self.name_count = 1
因为有较多的限制,所以把错误的信息汇总,将字符串的改变作为判断的指标。
def confirm_account(self):
"""确认账号是否为正确格式"""
account_str = "长度为5-15位,由数字和字母组成"
self.tip_account.setText(account_str)
self.tip_account.setStyleSheet("color:black;")
self.account_count = 0
account = self.lineEdit_account.text()
if len(account) == 0:
account_str = "账号为空"
elif len(account) < 5:
account_str = "账号长度低于5位"
else:
count = judge_account( account) #在数据库中查找是否有相同的账号
if count == 1:
account_str = "账号已存在"
if account_str != "长度为5-15位,由数字和字母组成":
QMessageBox.warning(self, "警告", account_str)
self.tip_account.setText( account_str)
self.tip_account.setStyleSheet("color:red;") #把标签信息修改为红色
self.account_count = 1
因为在点击“注册”按钮的时候会重新调用三个 confirm_ 函数,所以在 confirm_account() 函数不应该添加“账号可以使用”的提示,但不添加的话,账号可以使用的时候点击“√”按钮没有反应会很单调,所以特意多添加了一个函数。
def action_confirm_account(self):
"""在动作上多加一个成功提示框"""
self.confirm_account()
if self.account_count == 0:
QMessageBox.information(self, '恭喜', '这个账号可以使用!')
① self.lineEdit_password.clear():
clear() 清空这个输入框的内容,不能在弹出消息对话框后直接使用,会崩溃,要用 reply 的格式,即点击消息对话框上对应的按钮后才进行清空。
② 嵌套 if-elif 的格式:
使对话框不会多次弹出,先校验 “密码” 输入框的格式,再校验 两次密码是否一致的问题,就不用校验 “确认密码” 输入框的格式了。
def confirm_password(self):
"""确认密码是否为正确格式"""
self.tip_password.setText( "长度为6-15位,由数字和字母组成")
self.tip_confirmpassword.setText( "再次确认密码")
self.tip_password.setStyleSheet("color:black;")
self.tip_confirmpassword.setStyleSheet("color:black;")
self.password_count = 0
password = self.lineEdit_password.text()
con_password = self.lineEdit_confirmpassword.text()
if len(password) == 0:
QMessageBox.warning(self, "警告", "密码为空")
self.tip_password.setText("密码为空")
self.tip_password.setStyleSheet("color:red;")
self.password_count = 1
elif len(password) < 6:
QMessageBox.warning(self, "警告", "密码长度低于6位")
self.tip_password.setText("密码长度低于6位")
self.tip_password.setStyleSheet("color:red;")
self.password_count = 1
elif password != con_password:
reply = QMessageBox.critical(self, '错误', '两次输入的密码不一致',
QMessageBox.Retry, QMessageBox.Retry)
self.tip_confirmpassword.setText("两次输入的密码不一致")
self.tip_confirmpassword.setStyleSheet("color:red;") #把标签信息修改为红色
if reply == QMessageBox.Retry:
self.lineEdit_password.clear()
self.lineEdit_confirmpassword.clear()
self.password_count = 1
①把符合注册规则的账号、用户名和密码加入到系统账号的数据库里面;
②创建单独属于这个账号的数据库。
def add_account(self):
"""注册成功后的操作"""
account = self.lineEdit_account.text() #将 新 注册的账号录入系统的账号数据库
name = self.lineEdit_name.text()
password = self.lineEdit_password.text()
cn = sqlite3.connect(db_name_account) #连接系统账号数据库
sql = '''insert into Accounts
( Account, Aname, Password)
values( '%s', '%s','%s')
''' % ( account, name, password)
cn.execute(sql)
cn.commit()
dbname = account + '.db' # 创建独属于这个账户的学生数据库
create_stu_db(dbname)
①开头的 if-if :
为了多个输入框错误的时候,不弹出多个消息对话框;
只有当前面的输入框输入正确时,才会检验后面的输入框。
②后面的 if 的三个==:
必须三个函数的 _count 都等于0才能注册成功,即通过三个函数的校验。
③注册成功后会隐藏本窗口,之前的登录窗口没有关掉,即可以进行登录了。
def on_button_signin(self): #按下“注册”的按钮
self.confirm_name()
if self.name_count == 0:
self.confirm_account()
if self.account_count == 0:
self.confirm_password()
if self.name_count == 0 and self.account_count == 0 \
and self.password_count == 0:
self.add_account()
reply = QMessageBox.information(self, '恭喜', '注册成功!',
QMessageBox.Ok, QMessageBox.Ok)
if reply == QMessageBox.Ok:
self.hide()
class FormSignIn(QWidget, Ui_SignIn):
调用视图代码
def __init__(self, parent=None):
super(FormSignIn, self).__init__(parent)
self.setupUi(self)
①匹配账号和密码;
②当匹配成功的时候打开系统的主窗口。
def on_button_signin(self): #按下“登录”的按钮
account = self.lineEdit_account.text()
count = judge_account(account)
if count != 1:
reply = QMessageBox.warning(self, "警告", "账号不存在,请重新输入",
QMessageBox.Retry, QMessageBox.Retry)
if reply == QMessageBox.Retry:
self.lineEdit_account.clear()
self.lineEdit_password.clear()
else:
password = self.lineEdit_password.text()
count = judge_ac_and_pw(account, password)
if count == 1:
reply = QMessageBox.information(self, '恭喜', '登录成功!',
QMessageBox.Ok, QMessageBox.Ok)
if reply == QMessageBox.Ok:
self.hide()
self.mywindow = MainWindow()
self.mywindow.account = account
self.mywindow.show()
else:
reply = QMessageBox.warning(self, "警告", "密码错误",
QMessageBox.Retry, QMessageBox.Retry)
if reply == QMessageBox.Retry:
self.lineEdit_password.clear()
打开注册的窗口,先创建一个注册类的实例对象,再show()。
def on_button_signup(self): #按下“注册账号”的按钮
self.signup = FormSignUp()
self.signup.show()
如果文章对你有帮助,点赞是对我最好的鼓励了!