PyQt5学生成绩信息系统(一):登录注册窗口(包含窗口跳转、连接数据库等)

目录

  • 一、前言:
    • 1、实现效果
    • 2、亮点:
    • 3、思路简介:
  • 二、数据库
    • 1、思路:
    • 2、代码:
  • 三、视图代码
    • 注册和登录窗口的视图代码:
  • 四、逻辑代码
    • 1、需要导入的包:
    • 2、可共用的代码:
      • (1)common( cn, sql):
      • (2)judge_account( account):
      • (3)judge_ac_and_pw( account, password):
    • 3、注册窗口的逻辑代码:
      • (1)__init__(self, parent=None):
      • (2)all_validator(self):
      • (3)confirm_name(self):
      • (4)confirm_account(self):
      • (5)action_confirm_account(self):
      • (6)confirm_password(self):
      • (7)add_account(self):
      • (8)on_button_signin(self):
    • 4、登录窗口的逻辑代码:
      • (1) __init__(self, parent=None):
      • (2)on_button_signin(self):
      • (3)on_button_signup(self):

一、前言:

这是个学生成绩信息系统的窗口化,结合了sqlite3。
刚写好登录注册窗口,会陆续更新。
窗口设计用的是Qtdesinger,可参考:记录分享学习Qt设计师的文章及简介

1、实现效果

PyQt5学生成绩信息系统(一):登录注册窗口(包含窗口跳转、连接数据库等)_第1张图片
PyQt5学生成绩信息系统(一):登录注册窗口(包含窗口跳转、连接数据库等)_第2张图片

2、亮点:

1、能在出错的时候在注册页面显示错误信息,Label处的字体会变化,且标红;
2、账号输入框后有一个图标(action)能进行判断;
3、在注册成功的时候能创建一个独属于他的数据库。
PyQt5学生成绩信息系统(一):登录注册窗口(包含窗口跳转、连接数据库等)_第3张图片

3、思路简介:

(1)传统的登录界面和注册界面;
(2)在注册窗口能进行各种限定,比如账号和密码的限定长度,以及验证两次密码的一致(后来美化了消息提示,用了四个用于提示的标签);
(3)注册成功将往账号数据库里面添加这个账号的信息,并创建一个独属于这个账号的数据库;
(4)在账号窗口能进行验证账号的正确性;
(5)连接两个窗口的相互跳转:
①登录窗口能打开注册窗口,此时登录窗口 不 自动关闭;
②注册成功后 自动关闭 注册窗口,回到登录窗口,即使之前关掉了登录窗口,重新打开即可。



二、数据库

1、思路:

(1)一个数据库用来存放系统的账号密码和用户名信息;
(2)一个账号注册成功就多一个独属于它的数据库,存放学生成绩信息。

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

四、逻辑代码

1、需要导入的包:

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 * #导入登录的视图代码

2、可共用的代码:

(1)common( cn, sql):

将数据从sql格式转换成 列表 镶嵌 字典 的格式并返回。
超级好用的一个函数,经常被我用于提取数据库里面的信息。

def common( cn, sql):
    """将数据从sql格式转换成列表镶嵌字典的格式并返回"""
    cursor = cn.execute(sql)
    information = []
    for row in cursor:
        information.append( row)
    return information

(2)judge_account( account):

判断账号是否已经存在:
①在注册时如果已经存在就不能重复;
②在登录时如果不存在要进行提示。

(3)judge_ac_and_pw( account, password):

在登录时要判断账号和密码是否匹配。

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

3、注册窗口的逻辑代码:

class FormSignUp(QWidget, Ui_SignUp):

(1)init(self, parent=None):

①调用视图代码;
② 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)

(2)all_validator(self):

限制账号和用户名只能输入数字和密码。
验证器不能和 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)

(3)confirm_name(self):

不限制用户名的命名格式,就只限制了“不能为空”,当为空的时候会弹出警告的消息窗口,并在提示的标签改变文字并标红。
① 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

(4)confirm_account(self):

因为有较多的限制,所以把错误的信息汇总,将字符串的改变作为判断的指标。

 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

(5)action_confirm_account(self):

因为在点击“注册”按钮的时候会重新调用三个 confirm_ 函数,所以在 confirm_account() 函数不应该添加“账号可以使用”的提示,但不添加的话,账号可以使用的时候点击“√”按钮没有反应会很单调,所以特意多添加了一个函数。

    def action_confirm_account(self):
        """在动作上多加一个成功提示框"""
        self.confirm_account()
        if self.account_count == 0:
            QMessageBox.information(self, '恭喜', '这个账号可以使用!')

(6)confirm_password(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

(7)add_account(self):

①把符合注册规则的账号、用户名和密码加入到系统账号的数据库里面;
②创建单独属于这个账号的数据库。

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)

(8)on_button_signin(self):

①开头的 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()

4、登录窗口的逻辑代码:

class FormSignIn(QWidget, Ui_SignIn):

(1) init(self, parent=None):

调用视图代码

def __init__(self, parent=None):
        super(FormSignIn, self).__init__(parent)
        self.setupUi(self)

(2)on_button_signin(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()


(3)on_button_signup(self):

打开注册的窗口,先创建一个注册类的实例对象,再show()。

def on_button_signup(self): #按下“注册账号”的按钮
	self.signup = FormSignUp()
    self.signup.show()

如果文章对你有帮助,点赞是对我最好的鼓励了!

你可能感兴趣的:(PyQt5学生成绩信息系统)