Python实现简单的学生选课管理系统(带界面,C/S结构,多线程)

目录

一,前言

二,准备与配置

(1)实现环境:

(2)需求分析与设计:

(3)数据库准备与设置:

(4)需要下载的Python库:

三,代码调整

(1)数据库替换

(2)图片替换

(3)路径修改:

文件路径示例:

四,运行演示

(1)服务端

界面展示

(2)客户端

登录界面

教务处:

学院:

学生:

五,可能存在的问题与解决

(1)如下图片所示:​

六,代码展示

服务端代码:

客户端代码:

七,总结


一,前言

这是由python实现简单的学生选课管理系统,分为服务端与客户端,使用socket进行通信,可以对数据库进行连接操作,使用PYQT5实现界面显示,客户端通过socket通信连接服务端,并不能直接对数据库进行操作,服务端经过验证了客户端身份后,通过接收客户端相关的请求,完成对数据库对应的操作;支持多个用户端对服务端进行连接。(文末有实现的代码,但不可直接运行,需要以下的步骤进行一些修改)

二,准备与配置

(1)实现环境:

实现语言:python3

数据库类型:MySql

(2)需求分析与设计:

教务处:

教务处的管理人员录入全校的课程基本信息和本学期的课程授课教师、地点、时间。
当学生退学时,由教务处的管理人注销学生基本信息
如果开课之后,学生要求退课,则由教务处的工作人员为学生注销所选课程;
允许学生休学,教务处为休学的退学做学籍冻结处理;复学后为其办理解冻处理;
教务处为学生办理注册手续;没有办理学期注册的学生不能选课;

学院:

在学生入学的时候,学院的管理人员录入学生基本信息;
学院管理员可以查询学生的选课信息、可以查询课程基本信息、学生基本信息;
学期末,学院工作人员负责录入学生的成绩。

学生:

学生登录系统选课,选课成功后信息存入数据库中,学生自己可以查询选课的情况;
学生选课不成功的情况有:
所选课程的先修课还没有记录,系统提示“缺先修课,选课失败”;
所选课程的上课时间有冲突,系统提示“上课时间有冲突,选课失败”;
学生所选课程的学分最多不能超18学分。
学生可以注销所选课程。

ER图:

(3)数据库准备与设置:

如果第一次安装Mysql数据库的话,这里MySql的初次配置教程链接:http://t.csdnimg.cn/96wV7

如果不是的话,继续下面的

创建数据库:

CREATE DATABASE SJKDZY;

需要创建以下四个表(附MySql代码):

用户信息表:

# 创建用户表
create table user_table(
    id int primary key not null auto_increment comment '自动编号',
    type char(10) comment '账户类型,默认为学生',
    name varchar(20) not null comment '账户名',
    pwd_hash char(20) not null comment '账户密码'
)comment '用户表';

学生信息表:

# 创建学生信息表
create table student_table(
    sid varchar(20) primary key comment '学号',
    name char(20) not null comment '学生姓名',
    gender char(2) check ( gender='男' or gender='女' ) comment '性别',
    age int check ( age>=0 or age<=100 ) comment '年龄',
    address char(20) comment '学生籍贯',
    sus bool default FALSE comment '休学状态',
    reg bool default FALSE comment '注册状态'
)comment '学生信息表';

课程信息表:

# 创建课程信息表
create table course_table(
    cid varchar(20) primary key comment '课程编号',
    name char(20) not null comment '课程名',
    classroom char(20) comment '授课教室',
    teacher char(10) comment '任课教师',
    date char(50) comment '上课时间',
    pre_cid varchar(20) comment '先导课编号',
    credit tinyint check ( credit >= 0 and credit <=100 ) comment '课程学分',
    note varchar(50) comment '备注',
    done_date char(10) comment '退课截止时间'
)comment '课程信息表';

选课信息表:

# 创建成绩表
create table score_table(
    sid varchar(20) not null comment '学生学号',
    cid varchar(20) not null comment '课程编号',
    score tinyint check ( score>=0 and score<=100 ) comment '成绩',
    delapp char(2) default '0' comment '退课标志',
    constraint score_table_to_student foreign key(sid) references student_table (sid) on update cascade on delete cascade,  # 设置外键,与主键保持同步
    constraint score_table_to_class foreign key(cid) references course_table (cid) on update cascade on delete cascade
)comment '学生成绩表';

临时表:

# 创建退学学生表
create table drop_out_student_table(
    sid varchar(20) primary key comment '学号',
    name char(20) not null comment '学生姓名',
    gender char(2) check ( gender='男' or gender='女' ) comment '性别',
    age int check ( age>=0 or age<=100 ) comment '年龄',
    address char(20) comment '学生籍贯',
    drop_out_date varchar(50) comment '退学时间'
)comment '退学学生信息表';

(4)需要下载的Python库:

PYQT5

Pyqt5-tools

pymysql

pysm4

三,代码调整

(1)数据库替换

需要将服务端以下位置代码中的数据库名与密码更改为自己数据库的

class Mysql_program(object):
    """
    用可以实现节点与数据库进行连接,以及完成数据库的基本操作
    """
    @staticmethod
    def get_conn():
        """
        获取MySQL链接
        :return: mysql connection
        """
        return pymysql.connect(
            host='localhost',  # 指定连接的主机类型
            user='root',  # 用户类型
            password='1234567890',  # -----------在这里!----------------------
            database="sjkdzy",      # -----------在这里!----------------------
            charset='utf8'
        )

(2)图片替换

需要将服务端与客户端以下位置中代码改为自己的logo图片位置

class main_program(object):
    def __init__(self, main_window):
        super().__init__()
        self.window = main_window
        self.window.setWindowIcon(QIcon('校徽1.png'))  # --------在这里!-----------------
        self.init_ui()

需要将客户端以下位置中代码改为自己的GIF图片位置,大小为50x50像素

class login_window(object):
    """
    登录窗口的实现
    """
    def __init__(self, main_window):
        super().__init__()
        self.main_window = main_window
        self.jwc_window = jwc_window()
        self.xy_window = xy_window()
        self.student_window = student_window()

    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.label = QtWidgets.QLabel(self.centralwidget)
        self.label.setGeometry(100, 20, 200, 60)  # QtCore.QRect(80, 30, 131, 16)
        self.label.setObjectName("label")

        self.gif = QMovie('bear.gif')  # ---------------------在这里!-----------------

(3)路径修改:

需要将服务端与客户端以下位置中的代码修改为自己的路径:

if __name__ == "__main__":
    os.environ['QT_QPA_PLATFORM_PLUGIN_PATH'] = "这里修改为自己QT5的plugins路径"  # 在这里!
    app = QApplication(sys.argv)

    window1 = QMainWindow()

    program = Main_program(window1)

    window1.show()

    sys.exit(app.exec_())
文件路径示例:

 

四,运行演示

(1)服务端

界面展示

(2)客户端

登录界面

教务处:

学院:

学生:

五,可能存在的问题与解决

(1)如下图片所示:

添加以下代码,记得修改为自己的QT5的plugins路径:

import os
os.environ['QT_QPA_PLATFORM_PLUGIN_PATH'] = "自己的项目名\.venv\Lib\site-packages\PyQt5\Qt5\plugins"  # 修复QT问题,添加为自己的plugins路径

六,代码展示

服务端代码:

import os
import sys
import pymysql
import socket
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QApplication, QMainWindow, QTableWidgetItem, QAbstractItemView, QMessageBox
import json
import pysm4
import random
import threading
import time

class Sever_window(object):

    def __init__(self, main_window):
        super().__init__()
        self.main_window = main_window

    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(800, 600)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.horizontalLayoutWidget_2 = QtWidgets.QWidget(self.centralwidget)
        self.horizontalLayoutWidget_2.setGeometry(QtCore.QRect(9, 10, 781, 51))
        self.horizontalLayoutWidget_2.setObjectName("horizontalLayoutWidget_2")
        self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget_2)
        self.horizontalLayout_2.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout_2.setObjectName("horizontalLayout_2")
        spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_2.addItem(spacerItem)
        self.label = QtWidgets.QLabel(self.horizontalLayoutWidget_2)
        self.label.setObjectName("label")
        self.horizontalLayout_2.addWidget(self.label)
        spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_2.addItem(spacerItem1)
        self.commandLinkButton = QtWidgets.QCommandLinkButton(self.horizontalLayoutWidget_2)
        self.commandLinkButton.setObjectName("commandLinkButton")
        self.horizontalLayout_2.addWidget(self.commandLinkButton)
        self.verticalLayoutWidget_2 = QtWidgets.QWidget(self.centralwidget)
        self.verticalLayoutWidget_2.setGeometry(QtCore.QRect(10, 70, 241, 481))
        self.verticalLayoutWidget_2.setObjectName("verticalLayoutWidget_2")
        self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.verticalLayoutWidget_2)
        self.verticalLayout_2.setContentsMargins(0, 0, 0, 0)
        self.verticalLayout_2.setObjectName("verticalLayout_2")
        self.label_2 = QtWidgets.QLabel(self.verticalLayoutWidget_2)
        self.label_2.setObjectName("label_2")
        self.verticalLayout_2.addWidget(self.label_2)
        self.tableWidget = QtWidgets.QTableWidget(self.verticalLayoutWidget_2)
        self.tableWidget.setObjectName("tableWidget")
        self.tableWidget.setColumnCount(2)
        self.tableWidget.setRowCount(0)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(0, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(1, item)
        self.verticalLayout_2.addWidget(self.tableWidget)
        self.verticalLayoutWidget_3 = QtWidgets.QWidget(self.centralwidget)
        self.verticalLayoutWidget_3.setGeometry(QtCore.QRect(540, 70, 251, 481))
        self.verticalLayoutWidget_3.setObjectName("verticalLayoutWidget_3")
        self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.verticalLayoutWidget_3)
        self.verticalLayout_3.setContentsMargins(0, 0, 0, 0)
        self.verticalLayout_3.setObjectName("verticalLayout_3")
        self.label_3 = QtWidgets.QLabel(self.verticalLayoutWidget_3)
        self.label_3.setObjectName("label_3")
        self.verticalLayout_3.addWidget(self.label_3)
        self.tableWidget_2 = QtWidgets.QTableWidget(self.verticalLayoutWidget_3)
        self.tableWidget_2.setObjectName("tableWidget_2")
        self.tableWidget_2.setColumnCount(2)
        self.tableWidget_2.setRowCount(0)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget_2.setHorizontalHeaderItem(0, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget_2.setHorizontalHeaderItem(1, item)
        self.verticalLayout_3.addWidget(self.tableWidget_2)
        # 用户类型
        self.label_type = QtWidgets.QLabel(self.centralwidget)  # 账户类型标签
        self.label_type.setGeometry(QtCore.QRect(260, 270, 70, 30))
        self.label_type.setObjectName("label_type")
        self.comboBox = QtWidgets.QComboBox(self.centralwidget)
        self.comboBox.setGeometry(QtCore.QRect(340, 270, 120, 30))
        self.comboBox.setObjectName("comboBox")
        self.comboBox.addItem("")
        self.comboBox.addItem("")
        self.comboBox.addItem("")
        # 用户数据输入
        self.label_4 = QtWidgets.QLabel(self.centralwidget)  # 账户名标签
        self.label_4.setGeometry(QtCore.QRect(260, 310, 70, 30))
        self.label_4.setObjectName("label_4")
        self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)  # 账户名输入栏
        self.lineEdit.setGeometry(QtCore.QRect(340, 309, 180, 30))
        self.lineEdit.setObjectName("lineEdit")
        self.label_5 = QtWidgets.QLabel(self.centralwidget)  # 账户密码输入标签
        self.label_5.setGeometry(QtCore.QRect(260, 350, 70, 30))
        self.label_5.setObjectName("label_5")
        self.lineEdit_2 = QtWidgets.QLineEdit(self.centralwidget)  # 账户密码输入栏
        self.lineEdit_2.setGeometry(QtCore.QRect(340, 350, 180, 30))
        self.lineEdit_2.setObjectName("lineEdit_2")
        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton.setGeometry(QtCore.QRect(270, 400, 75, 30))
        self.pushButton.setObjectName("pushButton")
        self.pushButton_2 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_2.setGeometry(QtCore.QRect(440, 400, 75, 30))
        self.pushButton_2.setObjectName("pushButton_2")
        self.label_6 = QtWidgets.QLabel(self.centralwidget)
        self.label_6.setGeometry(QtCore.QRect(260, 440, 300, 30))
        self.label_6.setObjectName("label_6")
        self.textEdit = QtWidgets.QTextEdit(self.centralwidget)
        self.textEdit.setGeometry(QtCore.QRect(260, 70, 271, 190))
        self.textEdit.setObjectName("textEdit")
        self.lineEdit_3 = QtWidgets.QLineEdit(self.centralwidget)
        self.lineEdit_3.setGeometry(QtCore.QRect(260, 500, 161, 30))
        self.lineEdit_3.setObjectName("lineEdit_3")
        self.pushButton_3 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_3.setGeometry(QtCore.QRect(440, 500, 75, 30))
        self.pushButton_3.setObjectName("pushButton_3")
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 30))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "选课管理系统服务端"))
        self.label.setText(_translate("MainWindow", "选课管理系统服务端"))
        self.commandLinkButton.setText(_translate("MainWindow", "安全退出"))
        self.commandLinkButton.clicked.connect(self.exit_button)
        self.label_2.setText(_translate("MainWindow", "用户状态列表"))
        item = self.tableWidget.horizontalHeaderItem(0)
        item.setText(_translate("MainWindow", "用户名"))
        item = self.tableWidget.horizontalHeaderItem(1)
        item.setText(_translate("MainWindow", "用户状态"))
        self.label_3.setText(_translate("MainWindow", "用户请求列表"))
        item = self.tableWidget_2.horizontalHeaderItem(0)
        item.setText(_translate("MainWindow", "用户名"))
        item = self.tableWidget_2.horizontalHeaderItem(1)
        item.setText(_translate("MainWindow", "用户请求"))
        self.label_type.setText(_translate("MainWindow", "类型:"))
        self.label_4.setText(_translate("MainWindow", "账户名:"))
        self.lineEdit.setPlaceholderText("输入用户名")
        self.label_5.setText(_translate("MainWindow", "密码:"))
        self.lineEdit_2.setPlaceholderText("输入或修改密码")
        self.pushButton.setText(_translate("MainWindow", "修改"))
        self.pushButton.clicked.connect(self.alter_client_pwd_function)
        self.pushButton_2.setText(_translate("MainWindow", "添加"))
        self.pushButton_2.clicked.connect(self.create_client_function)
        self.label_6.setText(_translate("MainWindow", "等待操作..."))
        self.lineEdit_3.setPlaceholderText("输入MySql语句")
        self.pushButton_3.setText(_translate("MainWindow", "执行"))
        self.pushButton_3.clicked.connect(self.top_query_function)
        self.comboBox.setItemText(0, _translate("MainWindow", "教务处"))
        self.comboBox.setItemText(1, _translate("MainWindow", "学院"))
        self.comboBox.setItemText(2, _translate("MainWindow", "学生"))
        # 绑定信号
        # Signal_program.update_client_state.connect(self.update_client_state_list_show)

    def update_client_state_list_show(self):
        """
        用于更新用户状态列表的方法
        :return: None
        """
        # 数据清空
        self.tableWidget.setRowCount(0)
        # 插入数据
        self.tableWidget.setRowCount(len(Main_program.client_name_list))
        self.tableWidget.setColumnCount(2)
        counter = 0
        for i, data in enumerate(Main_program.client_name_list):
            self.tableWidget.setItem(counter, 0, QTableWidgetItem(data))
            self.tableWidget.setItem(counter, 1, QTableWidgetItem(Main_program.client_state_list[i]))
            counter += 1
        self.tableWidget.setEditTriggers(QAbstractItemView.NoEditTriggers)

    def update_client_request_list_show(self):
        """
        用于更新用户请求列表的方法
        :return: None
        """
        # 数据清空
        self.tableWidget_2.setRowCount(0)
        # 插入数据
        self.tableWidget_2.setRowCount(len(Main_program.client_request_name_list))
        self.tableWidget_2.setColumnCount(2)
        counter = 0
        for i, data in enumerate(Main_program.client_request_name_list):
            self.tableWidget_2.setItem(counter, 0, QTableWidgetItem(data))
            self.tableWidget_2.setItem(counter, 1, QTableWidgetItem(Main_program.client_request_data_list[i]))
            counter += 1
        self.tableWidget_2.setEditTriggers(QAbstractItemView.NoEditTriggers)

    def alter_client_pwd_function(self):
        """
        用于实现修改指定类型和用户密码的方法,并屏幕上显示操作结果
        :return: None
        """
        self.pushButton.clicked.disconnect()
        client_name = self.lineEdit.text()
        client_new_pwd = self.lineEdit_2.text()
        client_type = self.comboBox.currentText()
        self.label_6.setText("")
        if client_name == "":
            self.label_6.setText("用户名不可为空!")
        elif client_new_pwd == "":
            self.label_6.setText("密码不可为空!")
        else:
            data = Mysql_program.query_data(f"select * from user_table where name = '{client_name}' and type = '{client_type}';")
            if data == ():
                self.label_6.setText("不存在该用户!")
            else:
                if Mysql_program.insert_or_update_data(f"update user_table set pwd_hash = '{client_new_pwd}' where name = '{client_name}' and type = '{client_type}';") is True and Main_program.update_client_data_list(client_type, client_name, client_new_pwd) is True:
                    self.lineEdit.setText("")
                    self.lineEdit_2.setText("")
                    self.label_6.setText("修改成功!")
                else:
                    self.label_6.setText("修改失败!")
        self.pushButton.clicked.connect(self.alter_client_pwd_function)

    def create_client_function(self):
        """
        用于实现添加指定类型用户的方法,在屏幕上显示操作结果
        :return: None
        """
        self.pushButton_2.clicked.disconnect()
        client_type = self.comboBox.currentText()
        client_name = self.lineEdit.text()
        client_pwd = self.lineEdit_2.text()
        self.label_6.setText("")
        if client_name == "":
            self.label_6.setText("用户名不可为空!")
        elif client_pwd == "":
            self.label_6.setText("密码不可为空!")
        else:
            data = Mysql_program.query_data(f"select * from user_table where type = '{client_type}' and name = '{client_name}';")
            if data == ():
                if Mysql_program.insert_or_update_data(f"insert into user_table(type, name, pwd_hash) values('{client_type}', '{client_name}', '{client_pwd}');") is True:
                    self.label.setText("用户添加成功!")
                else:
                    self.label_6.setText("用户添加失败!")
            else:
                self.label_6.setText("该用户已存在!")
        self.pushButton_2.clicked.connect(self.create_client_function)

    def top_query_function(self):
        """
        该方法为实现自由查询的方法,并在屏幕上显示响应结果
        :return: None
        """
        self.pushButton_3.clicked.disconnect()
        query_data = self.lineEdit_3.text()
        self.label_6.setText("")
        if len(query_data) <= 6:
            self.label_6.setText("输入似乎无效!")
        elif "select" == query_data[0:6] or "insert into" == query_data[:11] or "update" == query_data[:6] or "delete" == query_data[:6]:
            if query_data[len(query_data)-1:len(query_data)] != ";":  # 自动添加结尾标志
                query_data += ';'
            self.lineEdit_3.setText("")
            self.label_6.setText("已执行")
            mode = 0
            if "select" not in query_data:
                mode = 1
            Sever_window.show_top_query_function(query_data, mode)
        else:
            self.label_6.setText("语法似乎无效!")
        self.pushButton_3.clicked.connect(self.top_query_function)

    @staticmethod
    def show_top_query_function(query_data, mode):
        flag = True
        if mode == 0:
            data = ()
            try:
                data = Mysql_program.query_data(query_data)
            except pymysql.err.ProgrammingError:
                flag = False
            finally:
                if flag is True:
                    if data == ():
                        QMessageBox.information(None, "NOTE", "未查询到数据!")
                    else:
                        show_data = ""
                        for item in data:
                            show_data += str(item) + "\n"
                        QMessageBox.information(None, "NOTE", show_data)
                else:
                    QMessageBox.critical(None, 'ERROR', '执行错误!', QMessageBox.Yes)
        else:
            data = False
            try:
                data = Mysql_program.insert_or_update_data(query_data)
            except pymysql.err.ProgrammingError:
                flag = False
            finally:
                if flag is True:
                    if data is True:
                        QMessageBox.information(None, "NOTE", "执行成功!")
                    else:
                        QMessageBox.warning(None, 'NOTE', '执行失败!', QMessageBox.Yes)
                else:
                    QMessageBox.critical(None, 'ERROR', '执行错误!', QMessageBox.Yes)

    def exit_button(self):
        """
        退出幅度按系统的方法,会根据当前是否已连接客户端,若有则提示尚有用户连接无法退出,反之则退出系统
        :return: NOne
        """
        if Connect_program.now_listen == 0:
            Main_program.work_flag = False
            time.sleep(0.1)
            exit()
        else:
            self.label_6.setText("")
            self.label_6.setText("尚有用户通信中,无法关闭!")


class Main_program(object):
    """
    系统主线程的类
    """
    client_name_list = []  # 用户名列表
    client_pwd_list = []  # 用户密码列表
    client_type_list = []  # 用户类型列表
    client_state_list = []  # 用户状态列表
    # 系统参数
    work_flag = False  # 服务器工作状态标志
    update_client_state_flag = False  # 用户状态信息列表更新标志
    client_request_old_counter = 0  # 用户请求计数
    client_request_now_counter = 0
    client_request_counter_max = 10  # 请求列表最大存储请求数量
    client_request_name_list = []
    client_request_data_list = []
    # 根窗口
    main_window = ''

    def __init__(self, main_window):
        super().__init__()
        self.window = main_window
        Main_program.main_window = main_window
        self.window.setWindowIcon(QIcon('校徽1.png'))  # ----------------------------------修改这里!
        self.init_ui()

    def init_ui(self):
        """
        系统数据准备,并启用服务端监听线程的方法
        :return: None
        """
        if Mysql_program.get_user_all_data() is True:  # 判断用户数据读取结果
            self.login_window = Sever_window(self.window)
            self.login_window.setupUi(self.window)
            self.login_window.update_client_state_list_show()
            # 改变工作状态标志
            Main_program.work_flag = True
            # 创建并开启用户状态列表更新线程
            th1 = threading.Thread(target=Main_program.show_client_state_process, args=(self,))
            th1.start()
            # 创建并开启用户请求列表更新线程
            th2 = threading.Thread(target=Main_program.show_client_request_process, args=(self, ))
            th2.start()
            # 创建并开启通信监听线程
            th3 = threading.Thread(target=Connect_program.listen_start)
            th3.setDaemon(True)  # 设置为守护线程
            th3.start()  # 开启服务端监听
        else:
            QMessageBox.information(self.window, "错误", "读取用户数据异常!")

    def show_client_state_process(self):
        """
        实现用户状态列表更新的线程方法
        :return: None
        """
        while Main_program.work_flag is True:
            if Main_program.update_client_state_flag is True:
                Main_program.update_client_state_flag = False
                Sever_window.update_client_state_list_show(self.login_window)

    @staticmethod
    def show_client_request_process(self):
        """
        实现用户请求列表更新的线程方法
        :return: None
        """
        while Main_program.work_flag is True:
            time.sleep(0.1)
            Main_program.client_request_now_counter = len(Main_program.client_request_name_list)
            if Main_program.client_request_now_counter == Main_program.client_request_old_counter:
                Main_program.client_request_old_counter += 1
                if Main_program.client_request_now_counter > Main_program.client_request_counter_max:
                    Main_program.client_request_name_list.remove(Main_program.client_request_name_list[0])
                    Main_program.client_request_data_list.remove(Main_program.client_request_data_list[0])
                Sever_window.update_client_request_list_show(self.login_window)

    @staticmethod
    def update_client_state_list(stype, name, state):
        """
        用于修改用户状态列表的方法
        :param stype: 用户类型
        :param name: 用户名
        :param state: 用户状态标志,1 在线,0 离线
        :return: None
        """
        for i, n in enumerate(Main_program.client_name_list):
            if n == name and Main_program.client_type_list[i] == stype:
                if str(state) == '1':
                    Main_program.client_state_list[i] = "在线"
                else:
                    Main_program.client_state_list[i] = "离线"
                break

    @staticmethod
    def update_client_data_list(stype, name, pwd):
        """
        用于更新用户密码信息列表的方法
        :param stype: 用户类型
        :param name: 用户名
        :param pwd: 用户新密码
        :return: True/False
        """
        flag = False
        for i, n in enumerate(Main_program.client_name_list):
            if n == name and Main_program.client_type_list[i] == stype:
                Main_program.client_pwd_list[i] = pwd
                flag = True
                break
        return flag


class Client_program(object):
    """
    用户在服务端的存在方式的类
    """
    def __init__(self, index, sock, flag):
        super().__init__()
        self.name = Main_program.client_name_list[int(index)]  # 获得用户名
        self.pwd = Main_program.client_pwd_list[int(index)]  # 获得用户密码
        self.type = Main_program.client_type_list[int(index)]  # 获得用户类型
        self.sock = sock  # 获得用户通信体
        self.connect_flag = flag

    def client_mid_start(self):
        """
        判断用户类型并启用对应用户的方法
        :return: None
        """
        if self.type == "教务处":
            Main_program.update_client_state_list(self.type, self.name, 1)
            Main_program.update_client_state_flag = True
            self.jwu_process()
        elif self.type == "学院":
            Main_program.update_client_state_list(self.type, self.name, 1)
            Main_program.update_client_state_flag = True
            self.xy_process()
        else:
            Main_program.update_client_state_list(self.type, self.name, 1)
            Main_program.update_client_state_flag = True
            self.student_process()

    def jwu_process(self):
        """
        用于处理教务处用户的线程方法,其中功能包括:
        课程录入:录入课程信息,向客户端返回处理结果
        退学处理:首先在退学学生信息表中查询目标学号以判断该学号是否已经进行了退学处理,
                判断在学生信息表中是否存在目标学生学生号,存在则进行处理,返回退学处理结果
        :return:None
        """
        while True:
            data = self.sock.recv(1024).decode()
            Main_program.client_request_name_list.append(self.name)
            Main_program.client_request_data_list.append(data)
            if data == "jwc_course_table_insert":  # 课程录入
                data = self.sock.recv(1024).decode()
                data = json.loads(data)
                course_cid = data['course_cid']
                course_name = data['course_name']
                course_classroom = data['course_classroom']
                course_teacher = data['course_teacher']
                course_date = data['course_date']
                course_pri_cid = data['course_pre_cid']
                course_credit = data['course_credit']
                course_note = data['course_note']
                course_done = data['course_done']
                # 判断数据插入结果
                if Mysql_program.insert_or_update_data(f"insert into course_table(cid, name, classroom, teacher, date, pre_cid, credit, note, done_date) values ('{course_cid}', '{course_name}', '{course_classroom}', '{course_teacher}', '{course_date}', '{course_pri_cid}', '{course_credit}', '{course_note}', '{course_done}');") is True:
                    # 返回插入结果
                    self.sock.send("TRUE".encode())
                else:
                    self.sock.send("FALSE".encode())
            elif data == "jwc_student_table_delete":  # 退学处理
                data = self.sock.recv(1024).decode()
                data = json.loads(data)
                student_sid = data["student_sid"]
                data = Mysql_program.query_data(f"select * from student_table where sid = '{student_sid}';")
                # 判断学生信息表中是否存在该学号
                if data == ():
                    # 判断是否在退学学生表中找到该学号
                    data = Mysql_program.query_data(f"select * from drop_out_student_table where sid = '{student_sid}';")
                    if data != ():
                        # 已经处理过
                        self.sock.send("HAVE_DONE".encode())
                    else:
                        # 无此学号
                        self.sock.send("NONE".encode())
                else:
                    student_sid = data[0]['sid']
                    student_name = data[0]['name']
                    student_sex = data[0]['gender']
                    student_age = data[0]['age']
                    student_address = data[0]['address']
                    student_exit_date = str(time.ctime())
                    # 判断是否移除了学生信息(包括学生信息表,选课信息表,用户信息表)
                    if Mysql_program.insert_or_update_data(f"delete from student_table where sid = '{student_sid}';") is True and Mysql_program.insert_or_update_data(f"delete from score_table where sid = '{student_sid}';") is True and Main_program.update_client_data_list(f"delete from user_table where type = '{self.type}' and name = '{student_name}';"):
                        if Mysql_program.insert_or_update_data(f"insert into drop_out_student_table(sid, name, gender, age, address, drop_out_date) values ('{student_sid}', '{student_name}', '{student_sex}', '{student_age}', '{student_address}', '{student_exit_date}');"):
                            self.sock.send("OK".encode())
                        else:
                            self.sock.send("ERROR".encode())
                    else:
                        self.sock.send("FALSE".encode())
            elif data == "jwc_score_table_delete":  # 退课处理
                data = self.sock.recv(1024).decode()
                data = json.loads(data)
                student_sid = data["student_sid"]
                course_cid = data["course_cid"]
                # 判断学生是否申请退该课程
                data = Mysql_program.query_data(f"select delapp from score_table where sid = '{student_sid}' and cid = '{course_cid}';")
                if data == ():
                    en_data = Mysql_program.query_data(f"select * from score_table where sid = '{student_sid}' and cid = '{course_cid}';")
                    if en_data == ():
                        data = "null"
                    else:
                        data = 'have'
                else:
                    data = data[0]['delapp']
                if data == '0':
                    self.sock.send("NONE_THIS".encode())
                elif data == "null":
                    self.sock.send("NONE_SID".encode())
                else:
                    # 判断删除该学号选课是否成功
                    if Mysql_program.insert_or_update_data(f"delete from score_table where sid = '{student_sid}' and cid = '{course_cid}';") is True:
                        self.sock.send("OK".encode())
                    else:
                        self.sock.send("FALSE".encode())
            elif data == "jwc_sus_update":  # 休复学处理
                 data = self.sock.recv(1024).decode()
                 data = json.loads(data)
                 student_sid = data["student_sid"]
                 mode = data["mode"]
                 if mode == "suspend":
                     data_list = Mysql_program.query_data(f"select sus from student_table where sid = '{student_sid}';")
                     # 判断该学生是否已经进行了休学操作
                     if str(data_list[0]['sus']) == '1':
                         self.sock.send("HAVE_DONE".encode())
                     else:
                         if Mysql_program.insert_or_update_data(f"update student_table set sus = TRUE where sid = '{student_sid}';") is True:
                             self.sock.send("OK".encode())
                         else:
                             self.sock.send("FALSE".encode())
                 else:
                     data = Mysql_program.query_data(f"select * from student_table where sid = '{student_sid}';")
                     if str(data[0]['sus']) == "0":
                         self.sock.send("HAVE_DONE".encode())
                     else:
                         if Mysql_program.insert_or_update_data(f"update student_table set sus = FALSE where sid = '{student_sid}';") is True:
                             self.sock.send("OK".encode())
                         else:
                             self.sock.send("FALSE".encode())
            elif data == "jwc_reg_update":  # 注册处理
                data = self.sock.recv(1024).decode()
                data = json.loads(data)
                student_sid = data['student_sid']
                data = Mysql_program.query_data(f"select reg from student_table where sid='{student_sid}';")
                # 判断该学号状况
                if data == ():
                    self.sock.send("NONE".encode())
                else:
                    if str(data[0]["reg"]) == "1":
                        self.sock.send("HAVE_DONE".encode())
                    else:
                        if Mysql_program.insert_or_update_data(f"update student_table set reg = TRUE where sid = '{student_sid}';") is True:
                            self.sock.send("OK".encode())
                        else:
                            self.sock.send("FALSE".encode())
            elif data == "jwc_pwd_update":  # 密码修改
                data = self.sock.recv(1024).decode()
                data = json.loads(data)
                old_pwd = data["old_pwd"]
                new_pwd = data["new_pwd"]
                if self.pwd == old_pwd:
                    if Mysql_program.insert_or_update_data(f"update user_table set pwd_hash = '{new_pwd}' where name = '{self.name}' and type = '{self.type}';") is True and Main_program.update_client_data_list(self.type, self.name, new_pwd) is True:
                        self.sock.send("OK".encode())
                    else:
                        self.sock.send("FALSE".encode())
                else:
                    self.sock.send("ERROR".encode())
            else:  # 退出
                self.sock.close()
                Main_program.update_client_data_list(self.type, self.name, 0)
                break
        Main_program.update_client_state_list(self.type, self.name, 0)
        Main_program.update_client_state_flag = True
        Connect_program.now_listen -= 1

    def xy_process(self):
        """
        实现学院用户进程的方法
        :return: None
        """
        while True:
            data = self.sock.recv(1024).decode()
            Main_program.client_request_name_list.append(self.name)
            Main_program.client_request_data_list.append(data)
            if data == "xy_student_table_insert":  # 学生信息录入
                data = self.sock.recv(1024).decode()
                data = json.loads(data)
                student_sid = data["student_sid"]
                student_name = data["student_name"]
                student_gender = data["student_gender"]
                student_age = int(data["student_age"])
                student_address = data["student_address"]
                data = Mysql_program.query_data(f"select * from student_table where sid = '{student_sid}';")
                if data == ():
                    if Mysql_program.insert_or_update_data(f"insert into student_table(sid, name, gender, age, address, sus, reg) values ('{student_sid}', '{student_name}', '{student_gender}', {student_age}, '{student_address}', FALSE, FALSE);") is True:
                       self.sock.send("OK".encode())
                    else:
                        self.sock.send("FALSE".encode())
                else:
                    self.sock.send("HAVE_DONE".encode())
            elif data == "xy_score_table_select":  # 选课查询
                data_list = Mysql_program.query_data(f"select sid, cid, score, delapp from score_table;")
                num_data = len(data_list)
                self.sock.send(str(num_data).encode())
                if num_data != 0:
                    time.sleep(0.1)
                    for data in data_list:
                        data = json.dumps(data)
                        self.sock.send(data.encode())
                        time.sleep(0.1)
            elif data == "xy_course_table_select":  # 课程信息查询
                data_list = Mysql_program.query_data(f"select cid, name, classroom, teacher, date, pre_cid, credit, note, done_date from course_table;")
                num_data = len(data_list)
                self.sock.send(str(num_data).encode())
                if num_data != 0:
                    time.sleep(0.1)
                    for data in data_list:
                        data = json.dumps(data)
                        self.sock.send(data.encode())
                        time.sleep(0.1)
            elif data == "xy_student_table_select":  # 学生信息查询
                data_list = Mysql_program.query_data(f"select sid, name, gender, age, address, sus, reg from student_table;")
                num_data = len(data_list)
                self.sock.send(str(num_data).encode())
                if num_data != 0:
                    time.sleep(0.1)
                    for data in data_list:
                        data = json.dumps(data)
                        self.sock.send(data.encode())
                        time.sleep(0.1)
            elif data == "xy_score_table_update":  # 成绩录入
                data = self.sock.recv(1024).decode()
                data = json.loads(data)
                student_sid = data["student_sid"]
                course_cid = data["course_cid"]
                course_score = data["course_score"]
                if Mysql_program.query_data(f"select sid from student_table where sid = '{student_sid}';") == ():
                    self.sock.send("NONE_SID".encode())
                elif Mysql_program.query_data(f"select cid from course_table where cid ='{course_cid}';") == ():
                    self.sock.send("NONE_CID".encode())
                elif Mysql_program.query_data(f"select * from score_table where sid = '{student_sid}' and cid = '{course_cid}';") == ():
                    self.sock.send("NONE_THIS".encode())
                else:
                    data = Mysql_program.query_data(f"select score from score_table where sid = '{student_sid}' and cid = '{course_cid}';")
                    if str(data[0]['score']) == "None":
                        if Mysql_program.insert_or_update_data(f"update score_table set score = '{course_score}' where sid = '{student_sid}' and cid = '{course_cid}';"):
                            self.sock.send("OK".encode())
                        else:
                            self.sock.send("FALSE".encode())
                    else:
                        self.sock.send("HAVE_DONE".encode())
            elif data == "xy_pwd_update":  # 密码修改
                data = self.sock.recv(1024).decode()
                data = json.loads(data)
                new_pwd = data["new_pwd"]
                if Mysql_program.insert_or_update_data(f"update user_table set pwd_hash ='{new_pwd}' where type = '{self.type}' and name = '{self.name}';") is True and Main_program.update_client_data_list(self.type, self.name, new_pwd) is True:
                    self.sock.send("OK".encode())
                else:
                    self.sock.send("FALSE".encode())
            else:  # 退出
                self.sock.close()
                Main_program.update_client_data_list(self.type, self.name, 0)
                break
        Main_program.update_client_state_list(self.type, self.name, 0)
        Main_program.update_client_state_flag = True
        Connect_program.now_listen -= 1

    def student_process(self):
        """
        实现学生用户的方法
        :return:
        """
        while True:
            data = self.sock.recv(1024).decode()
            Main_program.client_request_name_list.append(self.name)
            Main_program.client_request_data_list.append(data)
            if data == "stu_score_table_insert":  # 选课
                data = self.sock.recv(1024).decode()
                data = json.loads(data)
                course_cid = data["course_cid"]
                # 判断学生是否已注册
                data = Mysql_program.query_data(f"select reg from student_table where sid = '{self.name}';")
                if str(data[0]['reg']) == "1":
                    if Mysql_program.query_data(f"select * from course_table where cid = '{course_cid}';") == ():
                        self.sock.send("NONE_CID".encode())
                    elif Mysql_program.query_data(f"select * from score_table where cid = '{course_cid}' and sid = '{self.name}'") != ():
                        self.sock.send("HAVE_DONE".encode())
                    else:
                        # 判断选课时间是否冲突
                        flag_1 = True
                        dict_list = []
                        data_list = Mysql_program.query_data(f"select * from score_table where sid = '{self.name}';")
                        if data_list != ():
                            # 获得学生已选课的时间列表数据
                            course_date_list = Mysql_program.query_data(f"select date from course_table where cid in (select cid from score_table where sid = '{self.name}');")
                            # 获得目标选课的时间数据
                            choose_course_date = Mysql_program.query_data(f"select date from course_table where cid = '{course_cid}';")
                            # 数据格式修正
                            choose_course_date = Mysql_program.repair_to_dict(choose_course_date[0]['date'])
                            choose_course_date = json.loads(choose_course_date)
                            choose_day1 = ''
                            choose_day2 = ''
                            for choose_day1, choose_day2 in choose_course_date.items():
                                pass
                            for data in course_date_list:
                                dict_list.append(json.loads(Mysql_program.repair_to_dict(data['date'])))
                            for data in dict_list:
                                for k, v in data.items():
                                    if k == choose_day1:
                                        if v in choose_day2 or choose_day2 in v:
                                            flag_1 = False
                                if flag_1 is False:
                                    break
                        # 判断选课学分是否已达到18分
                        credit_counter = 0
                        data_list = Mysql_program.query_data(f"select credit from course_table where cid in (select cid from score_table where sid = '{self.name}');")
                        for data in data_list:
                            credit_counter += int(data['credit'])
                        target_credit = int(Mysql_program.query_data(f"select credit from course_table where cid = '{course_cid}';")[0]['credit'])
                        # 判断是否缺少先修课程
                        flag_2 = True
                        pre_cid = Mysql_program.query_data(f"select pre_cid from course_table where cid = '{course_cid}';")[0]['pre_cid']
                        if pre_cid != "000":
                            data = Mysql_program.query_data(f"select * from score_table where cid = '{pre_cid}' and sid = '{self.name}';")
                            if data == ():
                                flag_2 = False
                        if flag_1 is True:
                            if credit_counter + target_credit <= 18:  # 判断已选课程学分与即将选课学分之和是否大于 18
                                if flag_2 is True:
                                    # 判断是否成功选课
                                    if Mysql_program.insert_or_update_data(f"insert into score_table(sid, cid ) values ('{self.name}', '{course_cid}');") is True:
                                        self.sock.send("OK".encode())
                                    else:
                                        self.sock.send("FALSE".encode())
                                else:
                                    self.sock.send("NONE_PRECID".encode())
                            else:
                                self.sock.send("HAVE_FULL_CREDITS".encode())
                        else:
                            self.sock.send("TIME_ERROR".encode())
                else:
                    self.sock.send("NO_REGISTER".encode())
            elif data == "stu_score_table_update":  # 选课查询
                data_list = Mysql_program.query_data(f"select sid, cid, score, delapp from score_table where sid = '{self.name}';")
                num_data = str(len(data_list))
                self.sock.send(num_data.encode())
                if num_data != 0:
                    time.sleep(0.1)
                    for data in data_list:
                        data = json.dumps(data)
                        self.sock.send(data.encode())
                        time.sleep(0.1)
            elif data == "stu_score_table_delete":  # 退课请求
                data = self.sock.recv(1024).decode()
                data = json.loads(data)
                course_cid = data['course_cid']
                if Mysql_program.query_data(f"select cid from score_table where cid = '{course_cid}' and sid = '{self.name}';") == ():
                    self.sock.send("NONE_CID".encode())
                elif Mysql_program.compare_course_date(course_cid) is False:
                    data = Mysql_program.query_data(f"select score from score_table where sid = '{self.name}' and cid = '{course_cid}';")[0]['score']
                    if str(data) == "None":
                        if Mysql_program.insert_or_update_data(f"update score_table set delapp = TRUE where cid='{course_cid}' and sid='{self.name}';") is True:
                            self.sock.send("APPLY_DELETE_TRUE".encode())
                        else:
                            self.sock.send("APPLY_DELETE_FALSE".encode())
                    else:
                        self.sock.send("DENY_DELETE".encode())
                else:
                    if Mysql_program.insert_or_update_data(f"delete from score_table where cid = '{course_cid}' and sid = '{self.name}';") is True:
                        self.sock.send("OK".encode())
                    else:
                        self.sock.send("FALSE".encode())
            elif data == "stu_pwd_update":  # 修改密码
                data = self.sock.recv(1024).decode()
                data = json.loads(data)
                new_pwd = data["new_pwd"]
                if Mysql_program.insert_or_update_data(f"update user_table set pwd_hash = '{new_pwd}' where name = '{self.name}' and type = '{self.type}';") is True and Main_program.update_client_data_list(self.type, self.name, new_pwd) is True:
                    self.sock.send("OK".encode())
                else:
                    self.sock.send("FALSE".encode())
            else:  # 退出
                self.sock.close()
                Main_program.update_client_data_list(self.type, self.name, 0)
                break
        Main_program.update_client_state_list(self.type, self.name, 0)
        Main_program.update_client_state_flag = True
        Connect_program.now_listen -= 1


class Connect_program(object):
    """
    用于实现服务端与客户端进行通信的类
    """
    max_listen = 5  # 最大监听人数
    now_listen = 0  # 实时监听人数

    def __init__(self):
        super().__init__()

    @staticmethod
    def listen_start():
        """
        用于启动服务端监听的方法,将该方法作为线程使用,同时应该设置为守护线程,保证同时结束系统运行
        :return: None
        """
        sever = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sever.bind(('0.0.0.0', 8000))
        sever.listen()
        while Main_program.work_flag is True:
            while Connect_program.now_listen < Connect_program.max_listen:
                sock, address = sever.accept()
                # 创建并启用用户线程
                th = threading.Thread(target=Connect_program.mid_connect, args=(sock,))
                th.start()

    @staticmethod
    def mid_connect(sock):
        """
        用于中间验证用户身份的方法,若通过验证则通过该方法为用户创建用户线程
        此处的验证机制为:当服务端接收到正确的用户名与用户类型后,会随机生成数字,使用用户的密码加密后发往客户端,客户端需使用密码解密后,
                      在原数字的基础上加1,再将结果发往服务端,服务端验证后,将验证结果发往客户端
        :param sock: 通信体
        :return: None
        """
        Connect_program.now_listen += 1
        index = None
        flag = False
        find_flag = False
        # 接收用户类型
        client_type = sock.recv(1024).decode()
        # 接收用户名
        client_name = sock.recv(1024).decode()
        for index, name in enumerate(Main_program.client_name_list):
            if name == client_name and Main_program.client_type_list[index] == client_type:
                find_flag = True
                break
        if find_flag is True:
            sock.send("TRUE".encode())
            # 生成并发送验证数字
            num = str(random.randint(100, 5000))
            en_num = pysm4.encrypt_ecb(num, Main_program.client_pwd_list[index])
            sock.send(en_num.encode())
            # 接收结果
            re_num = sock.recv(1024).decode()
            num = str(int(num) + 1)
            # 验证并发送结果
            if re_num != 'ERROR':
                if re_num == num:
                    sock.send("TRUE".encode())
                    flag = True
                else:
                    sock.send("FALSE".encode())
        else:
            sock.send("FALSE".encode())
        if flag is True:  # 判断验证结果,启用用户线程
            client = Client_program(index, sock, True)
            th = threading.Thread(target=client.client_mid_start)
            th.start()
        else:
            Connect_program.now_listen -= 1
            sock.close()


class Mysql_program(object):
    """
    用可以实现节点与数据库进行连接,以及完成数据库的基本操作
    """
    @staticmethod
    def get_conn():
        """
        获取MySQL链接
        :return: mysql connection
        """
        return pymysql.connect(
            host='localhost',  # 指定连接的主机类型
            user='root',  # 用户类型
            password='3014007467',  # -------------------------------修改这里!
            database="sjkdzy",  # -----------------------------------修改这里!
            charset='utf8'
        )

    @staticmethod
    def query_data(sql):
        """
        根据SQL查询数据并且返回
        :param sql:SQL语句
        :return:list[dict]
        """
        conn = Mysql_program.get_conn()
        try:
            cursor = conn.cursor(pymysql.cursors.DictCursor)
            cursor.execute(sql)
            return cursor.fetchall()
        finally:
            conn.close()  # 关闭连接

    @staticmethod
    def insert_or_update_data(sql):
        """
        执行新增insert或者update的sql,返回执行结果
        :param sql: insert or update sql
        :return: True or flag
        """
        flag = False
        conn = Mysql_program.get_conn()
        try:
            cursor = conn.cursor()
            cursor.execute(sql)
            conn.commit()  # 注意这里只有commit才可以生效
            flag = True
        finally:
            conn.close()  # 关闭连接
            return flag

    @staticmethod
    def get_user_all_data():
        """
        用于获取用户所有数据,并添加数据至指定列表的方法,返回处理结果
        :return: flag
        """
        flag = False
        data_list = Mysql_program.query_data(f"select * from user_table;")
        if data_list == ():
            flag = True
        else:
            try:
                for data in data_list:
                    Main_program.client_name_list.append(data['name'])
                    Main_program.client_pwd_list.append(data['pwd_hash'])
                    Main_program.client_type_list.append(data['type'])
                    Main_program.client_state_list.append("离线")
                flag = True
            except KeyError:
                flag = False
            finally:
                pass
        return flag

    @staticmethod
    def repair_to_dict(test_str):
        """
        用于修正mysql中读取的时间字符串格式异常问题,返回修正后的字符串
        :param test_str: 待修正字符串
        :return: 修正后的字符串
        """
        end_str = ""
        for i in test_str:
            if i == "u":
                end_str += "\\" + i
            else:
                end_str += i
        return end_str

    @staticmethod
    def compare_course_date(cid):
        """
        用于实现判断选课是否已开课,返回判断结果
        :param cid: 课程号
        :return: True or flag
        """
        course_date = Mysql_program.query_data(f"select done_date from course_table where cid = '{cid}';")[0]['done_date']
        if course_date == ():
            return True
        else:
            now_date = Mysql_program.query_data("select now();")[0]['now()']
            if str(now_date) > course_date:
                return False
            else:
                return True

    @staticmethod
    def get_num(date_str):
        """
        从目标字符串获得数字的方法,返回数字字符串
        :param date_str: 目标字符串
        :return: 数字字符串
        """
        end_str = ''
        for data in date_str:
            if data.isdigit():
                end_str += data
        return end_str


if __name__ == "__main__":
    os.environ['QT_QPA_PLATFORM_PLUGIN_PATH'] = ""  # 这里需要改为自己QT的plugins的路径
    app = QApplication(sys.argv)

    window1 = QMainWindow()

    program = Main_program(window1)

    window1.show()

    sys.exit(app.exec_())

客户端代码:

import sys
import socket
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtGui import QIcon, QMovie
from PyQt5.QtWidgets import QApplication, QMainWindow, QTableWidgetItem, QAbstractItemView
import json
import pysm4
import time
import os

class Main_program(object):
    name = ''  # 用户名
    pwd = ''  # 用户密码
    type = ''  # 用户类型
    sock = None

    def __init__(self, main_window):
        super().__init__()
        self.window = main_window
        # self.window.setWindowIcon(QIcon('校徽1.png'))  # 这里可以自行决定是否添加logo图片
        self.init_ui()

    def init_ui(self):
        self.login_window = login_window(self.window)
        self.login_window.setupUi(self.window)

    @staticmethod
    def repair_to_dict(test_str):
        """
        用于修正mysql中读取的时间字符串格式异常问题,返回修正后的字符串
        :param test_str: 待修正字符串
        :return: 修正后的字符串
        """
        end_str = ""
        for i in test_str:
            if i == "u":
                end_str += "\\" + i
            else:
                end_str += i
        return end_str


class login_window(object):
    """
    登录窗口的实现
    """
    def __init__(self, main_window):
        super().__init__()
        self.main_window = main_window
        self.jwc_window = jwc_window()
        self.xy_window = xy_window()
        self.student_window = student_window()

    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.label = QtWidgets.QLabel(self.centralwidget)
        self.label.setGeometry(100, 20, 200, 60)  # QtCore.QRect(80, 30, 131, 16)
        self.label.setObjectName("label")

        self.gif = QMovie('bear.gif')
        self.label_gif = QtWidgets.QLabel(self.centralwidget)
        self.label_gif.setMovie(self.gif)
        self.label_gif.setGeometry(175, 90, 60, 60)  # QtCore.QRect(80, 30, 131, 16)
        self.label_gif.setObjectName("label_gif")
        self.gif.start()

        self.label_2 = QtWidgets.QLabel(self.centralwidget)
        self.label_2.setGeometry(QtCore.QRect(65, 230, 60, 30))
        self.label_2.setObjectName("label_2")
        self.label_3 = QtWidgets.QLabel(self.centralwidget)
        self.label_3.setGeometry(QtCore.QRect(65, 270, 60, 30))
        self.label_3.setObjectName("label_3")
        self.label_4 = QtWidgets.QLabel(self.centralwidget)
        self.label_4.setGeometry(QtCore.QRect(100, 400, 200, 30))
        self.label_4.setObjectName("label_4")
        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton.setGeometry(QtCore.QRect(100, 320, 80, 30))
        self.pushButton.setObjectName("pushButton")
        self.pushButton_2 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_2.setGeometry(QtCore.QRect(230, 320, 80, 30))
        self.pushButton_2.setObjectName("pushButton_2")
        self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
        self.lineEdit.setGeometry(QtCore.QRect(135, 230, 200, 30))
        self.lineEdit.setObjectName("lineEdit")
        self.lineEdit_2 = QtWidgets.QLineEdit(self.centralwidget)
        self.lineEdit_2.setGeometry(QtCore.QRect(135, 270, 200, 30))
        self.lineEdit_2.setObjectName("lineEdit_2")
        self.comboBox = QtWidgets.QComboBox(self.centralwidget)
        self.comboBox.setGeometry(QtCore.QRect(140, 190, 120, 30))
        self.comboBox.setObjectName("comboBox")
        self.comboBox.addItem("")
        self.comboBox.addItem("")
        self.comboBox.addItem("")
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 420, 22))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        # MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        MainWindow.setWindowTitle("选课管理系统")
        MainWindow.resize(400, 500)
        self.label.setText(_translate("MainWindow", "欢迎进入选课管理系统"))
        self.label_2.setText(_translate("MainWindow", "ID:"))
        self.lineEdit.setPlaceholderText("输入用户ID")
        self.label_3.setText(_translate("MainWindow", "密码:"))
        self.lineEdit_2.setPlaceholderText("输入密码")
        self.lineEdit_2.setEchoMode(QtWidgets.QLineEdit.Password)
        self.pushButton.setText(_translate("MainWindow", "登录"))
        self.pushButton.clicked.connect(self.login_connect)
        self.pushButton_2.setText(_translate("MainWindow", "退出"))
        self.pushButton_2.clicked.connect(self.login_exit)  # 连接信号与槽
        self.comboBox.setItemText(0, _translate("MainWindow", "教务处"))
        self.comboBox.setItemText(1, _translate("MainWindow", "学院"))
        self.comboBox.setItemText(2, _translate("MainWindow", "学生"))

    def login_connect(self):
        """
        登录按钮的直接方法,根据传入数据作出对应处理,或启用线程
        :return: None
        """
        self.pushButton.disconnect()  # 临时断开连接
        mode_data = self.comboBox.currentText()
        name_data = self.lineEdit.text()
        pwd_data = self.lineEdit_2.text()
        if Connect_program.client_start(name_data, pwd_data, mode_data) is True:
            if mode_data == "教务处":
                self.jwc_window.setupUi(self.main_window)
                self.jwc_window.name = name_data  # 记录用户名
                self.jwc_window.pwd = pwd_data  # 记录用户密码
            if mode_data == "学院":
                self.xy_window.setupUi(self.main_window)
                self.xy_window.name = name_data  # 记录用户名
                self.xy_window.pwd = pwd_data  # 记录用户密码
            if mode_data == "学生":
                self.student_window.setupUi(self.main_window)
                self.student_window.name = name_data  # 记录用户名
                self.student_window.pwd = pwd_data  # 记录用户密码
        else:
            self.label_4.setText("登录失败,请检查输入!")
            self.pushButton.clicked.connect(self.login_connect)

    def login_exit(self):
        sys.exit()


class jwc_window(object):
    """
    教务处窗口的实现
    """
    def __init__(self):
        super().__init__()
        self.type = "教务处"  # 记录用户类型
        self.name = None  # 记录用户名
        self.pwd = None  # 记录用户密码

    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.tabWidget = QtWidgets.QTabWidget(self.centralwidget)
        self.tabWidget.setGeometry(QtCore.QRect(20, 40, 800, 471))
        self.tabWidget.setObjectName("tabWidget")
        # 第一张表
        self.tab = QtWidgets.QWidget()
        self.tab.setObjectName("tab")
        self.label = QtWidgets.QLabel(self.tab)
        self.label.setGeometry(QtCore.QRect(20, 30, 80, 30))
        self.label.setObjectName("label")
        self.label_2 = QtWidgets.QLabel(self.tab)
        self.label_2.setGeometry(QtCore.QRect(260, 30, 100, 30))
        self.label_2.setObjectName("label_2")
        self.lineEdit = QtWidgets.QLineEdit(self.tab)
        self.lineEdit.setGeometry(QtCore.QRect(120, 30, 120, 30))
        self.lineEdit.setObjectName("lineEdit")
        self.lineEdit_2 = QtWidgets.QLineEdit(self.tab)
        self.lineEdit_2.setGeometry(QtCore.QRect(360, 30, 120, 30))
        self.lineEdit_2.setObjectName("lineEdit_2")
        self.label_3 = QtWidgets.QLabel(self.tab)
        self.label_3.setGeometry(QtCore.QRect(20, 80, 80, 30))
        self.label_3.setObjectName("label_3")
        self.label_4 = QtWidgets.QLabel(self.tab)
        self.label_4.setGeometry(QtCore.QRect(260, 80, 100, 30))
        self.label_4.setObjectName("label_4")
        self.lineEdit_3 = QtWidgets.QLineEdit(self.tab)
        self.lineEdit_3.setGeometry(QtCore.QRect(120, 80, 120, 30))
        self.lineEdit_3.setObjectName("lineEdit_3")
        self.lineEdit_4 = QtWidgets.QLineEdit(self.tab)
        self.lineEdit_4.setGeometry(QtCore.QRect(360, 80, 120, 30))
        self.lineEdit_4.setObjectName("lineEdit_4")
        self.label_5 = QtWidgets.QLabel(self.tab)
        self.label_5.setGeometry(QtCore.QRect(20, 130, 80, 30))
        self.label_5.setObjectName("label_5")
        self.label_6 = QtWidgets.QLabel(self.tab)
        self.label_6.setGeometry(QtCore.QRect(260, 130, 100, 30))
        self.label_6.setObjectName("label_6")
        self.lineEdit_5 = QtWidgets.QLineEdit(self.tab)
        self.lineEdit_5.setGeometry(QtCore.QRect(120, 130, 120, 30))
        self.lineEdit_5.setObjectName("lineEdit_5")
        self.lineEdit_6 = QtWidgets.QLineEdit(self.tab)
        self.lineEdit_6.setGeometry(QtCore.QRect(360, 130, 120, 30))
        self.lineEdit_6.setObjectName("lineEdit_6")
        self.label_7 = QtWidgets.QLabel(self.tab)
        self.label_7.setGeometry(QtCore.QRect(20, 180, 80, 30))
        self.label_7.setObjectName("label_7")
        self.label_8 = QtWidgets.QLabel(self.tab)
        self.label_8.setGeometry(QtCore.QRect(260, 180, 100, 30))
        self.label_8.setObjectName("label_8")
        self.lineEdit_7 = QtWidgets.QLineEdit(self.tab)
        self.lineEdit_7.setGeometry(QtCore.QRect(120, 180, 120, 30))
        self.lineEdit_7.setObjectName("lineEdit_7")
        self.lineEdit_8 = QtWidgets.QLineEdit(self.tab)
        self.lineEdit_8.setGeometry(QtCore.QRect(360, 180, 120, 30))
        self.lineEdit_8.setObjectName("lineEdit_8")
        self.label_delete = QtWidgets.QLabel(self.tab)
        self.label_delete.setGeometry(QtCore.QRect(20, 220, 150, 30))
        self.label_delete.setObjectName("label_delete")
        self.lineEdit_delete = QtWidgets.QLineEdit(self.tab)
        self.lineEdit_delete.setGeometry(QtCore.QRect(180, 220, 200, 30))
        self.lineEdit_delete.setObjectName("lineEdit_delete")
        self.pushButton_8 = QtWidgets.QPushButton(self.tab)
        self.pushButton_8.setGeometry(QtCore.QRect(20, 260, 80, 30))
        self.pushButton_8.setObjectName("pushButton_8")
        self.label_one = QtWidgets.QLabel(self.tab)
        self.label_one.setGeometry(QtCore.QRect(20, 300, 300, 30))
        self.label_one.setObjectName("label_two")
        # 第二张表
        self.tabWidget.addTab(self.tab, "")
        self.tab_2 = QtWidgets.QWidget()
        self.tab_2.setObjectName("tab_2")
        self.label_9 = QtWidgets.QLabel(self.tab_2)
        self.label_9.setGeometry(QtCore.QRect(40, 120, 170, 30))
        self.label_9.setObjectName("label_9")
        self.lineEdit_9 = QtWidgets.QLineEdit(self.tab_2)
        self.lineEdit_9.setGeometry(QtCore.QRect(220, 120, 170, 30))
        self.lineEdit_9.setObjectName("lineEdit_9")
        self.pushButton_9 = QtWidgets.QPushButton(self.tab_2)
        self.pushButton_9.setGeometry(QtCore.QRect(40, 190, 80, 30))
        self.pushButton_9.setObjectName("pushButton_9")
        self.label_two = QtWidgets.QLabel(self.tab_2)
        self.label_two.setGeometry(QtCore.QRect(40, 230, 300, 30))
        self.label_two.setObjectName("label_two")
        # 第三张表
        self.tabWidget.addTab(self.tab_2, "")
        self.tab_3 = QtWidgets.QWidget()
        self.tab_3.setObjectName("tab_3")
        self.label_10 = QtWidgets.QLabel(self.tab_3)
        self.label_10.setGeometry(QtCore.QRect(30, 90, 61, 30))
        self.label_10.setObjectName("label_10")
        self.lineEdit_10 = QtWidgets.QLineEdit(self.tab_3)
        self.lineEdit_10.setGeometry(QtCore.QRect(110, 90, 113, 30))
        self.lineEdit_10.setObjectName("lineEdit_10")
        self.label_11 = QtWidgets.QLabel(self.tab_3)
        self.label_11.setGeometry(QtCore.QRect(30, 130, 61, 30))
        self.label_11.setObjectName("label_11")
        self.lineEdit_11 = QtWidgets.QLineEdit(self.tab_3)
        self.lineEdit_11.setGeometry(QtCore.QRect(110, 130, 113, 30))
        self.lineEdit_11.setObjectName("lineEdit_11")
        self.pushButton_10 = QtWidgets.QPushButton(self.tab_3)
        self.pushButton_10.setGeometry(QtCore.QRect(30, 180, 80, 30))
        self.pushButton_10.setObjectName("pushButton_10")
        self.label_three = QtWidgets.QLabel(self.tab_3)
        self.label_three.setGeometry(QtCore.QRect(30, 220, 300, 30))
        self.label_three.setObjectName("label_three")
        # 第四张表
        self.tabWidget.addTab(self.tab_3, "")
        self.tab_4 = QtWidgets.QWidget()
        self.tab_4.setObjectName("tab_4")
        self.label_12 = QtWidgets.QLabel(self.tab_4)
        self.label_12.setGeometry(QtCore.QRect(40, 90, 120, 30))
        self.label_12.setObjectName("label_12")
        self.label_13 = QtWidgets.QLabel(self.tab_4)
        self.label_13.setGeometry(QtCore.QRect(40, 130, 120, 30))
        self.label_13.setObjectName("label_13")
        self.lineEdit_12 = QtWidgets.QLineEdit(self.tab_4)
        self.lineEdit_12.setGeometry(QtCore.QRect(190, 90, 120, 30))
        self.lineEdit_12.setObjectName("lineEdit_12")
        self.lineEdit_13 = QtWidgets.QLineEdit(self.tab_4)
        self.lineEdit_13.setGeometry(QtCore.QRect(190, 130, 120, 30))
        self.lineEdit_13.setObjectName("lineEdit_13")
        self.pushButton_11 = QtWidgets.QPushButton(self.tab_4)
        self.pushButton_11.setGeometry(QtCore.QRect(320, 90, 80, 30))
        self.pushButton_11.setObjectName("pushButton_11")
        self.pushButton_12 = QtWidgets.QPushButton(self.tab_4)
        self.pushButton_12.setGeometry(QtCore.QRect(320, 130, 80, 30))
        self.pushButton_12.setObjectName("pushButton_12")
        self.label_four = QtWidgets.QLabel(self.tab_4)
        self.label_four.setGeometry(QtCore.QRect(40, 170, 300, 30))
        self.label_four.setObjectName("label_four")
        self.label_four2 = QtWidgets.QLabel(self.tab_4)
        self.label_four2.setGeometry(QtCore.QRect(40, 210, 300, 30))
        self.label_four2.setObjectName("label_four2")
        # 第五张表
        self.tabWidget.addTab(self.tab_4, "")
        self.tab_5 = QtWidgets.QWidget()
        self.tab_5.setObjectName("tab_5")
        self.lineEdit_14 = QtWidgets.QLineEdit(self.tab_5)
        self.lineEdit_14.setGeometry(QtCore.QRect(200, 130, 120, 30))
        self.lineEdit_14.setObjectName("lineEdit_14")
        self.label_14 = QtWidgets.QLabel(self.tab_5)
        self.label_14.setGeometry(QtCore.QRect(40, 130, 150, 30))
        self.label_14.setObjectName("label_14")
        self.pushButton_13 = QtWidgets.QPushButton(self.tab_5)
        self.pushButton_13.setGeometry(QtCore.QRect(40, 200, 80, 30))
        self.pushButton_13.setObjectName("pushButton_13")
        self.label_five = QtWidgets.QLabel(self.tab_5)
        self.label_five.setGeometry(QtCore.QRect(40, 240, 150, 30))
        self.label_five.setObjectName("label_four")
        # 第六张表
        self.tabWidget.addTab(self.tab_5, "")
        self.tab_6 = QtWidgets.QWidget()
        self.tab_6.setObjectName("tab_6")
        self.label_old = QtWidgets.QLabel(self.tab_6)
        self.label_old.setGeometry(QtCore.QRect(40, 90, 150, 30))
        self.label_old.setObjectName("label_old")
        self.label_15 = QtWidgets.QLabel(self.tab_6)
        self.label_15.setGeometry(QtCore.QRect(40, 130, 150, 30))
        self.label_15.setObjectName("label_15")
        self.lineEdit_old = QtWidgets.QLineEdit(self.tab_6)
        self.lineEdit_old.setGeometry(QtCore.QRect(200, 90, 200, 30))
        self.lineEdit_old.setObjectName("lineEdit_old")
        self.lineEdit_15 = QtWidgets.QLineEdit(self.tab_6)
        self.lineEdit_15.setGeometry(QtCore.QRect(200, 130, 200, 30))
        self.lineEdit_15.setObjectName("lineEdit_15")
        self.pushButton_14 = QtWidgets.QPushButton(self.tab_6)
        self.pushButton_14.setGeometry(QtCore.QRect(40, 200, 80, 30))
        self.pushButton_14.setObjectName("pushButton_14")
        self.label_six = QtWidgets.QLabel(self.tab_6)
        self.label_six.setGeometry(QtCore.QRect(40, 240, 150, 30))
        self.label_six.setObjectName("label_six")
        # 第七张表
        self.tabWidget.addTab(self.tab_6, "")
        self.tab_7 = QtWidgets.QWidget()
        self.tab_7.setObjectName("tab_7")
        self.horizontalLayoutWidget = QtWidgets.QWidget(self.tab_7)
        self.horizontalLayoutWidget.setGeometry(QtCore.QRect(20, 10, 511, 421))
        self.horizontalLayoutWidget.setObjectName("horizontalLayoutWidget")
        self.horizontalLayout = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget)
        self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout.setObjectName("horizontalLayout")
        spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout.addItem(spacerItem)
        self.label_16 = QtWidgets.QLabel(self.horizontalLayoutWidget)
        self.label_16.setObjectName("label_16")
        self.horizontalLayout.addWidget(self.label_16)
        spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout.addItem(spacerItem1)
        self.pushButton_15 = QtWidgets.QPushButton(self.horizontalLayoutWidget)
        self.pushButton_15.setObjectName("pushButton_15")
        self.horizontalLayout.addWidget(self.pushButton_15)
        spacerItem2 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout.addItem(spacerItem2)
        self.tabWidget.addTab(self.tab_7, "")
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 579, 22))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        self.tabWidget.setCurrentIndex(0)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        # MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        MainWindow.setWindowTitle("选课管理系统")
        MainWindow.resize(850, 600)
        # 表一
        self.label.setText(_translate("MainWindow", "课程编号:"))
        self.label_2.setText(_translate("MainWindow", "课程名称:"))
        self.label_3.setText(_translate("MainWindow", "教学教室:"))
        self.label_4.setText(_translate("MainWindow", "任课教师:"))
        self.label_5.setText(_translate("MainWindow", "上课时间:"))
        self.label_6.setText(_translate("MainWindow", "先导课编号:"))
        self.label_7.setText(_translate("MainWindow", "课程学分:"))
        self.label_8.setText(_translate("MainWindow", "课程说明:"))
        self.label_delete.setText(_translate("MainWindow", "退课截止时间:"))
        self.lineEdit_delete.setPlaceholderText("格式:YYYY-MM-DD")
        self.pushButton_8.setText(_translate("MainWindow", "确定"))
        self.pushButton_8.clicked.connect(self.update_course)
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), _translate("MainWindow", "课程录入"))
        # 表二
        self.label_9.setText(_translate("MainWindow", "请输入退学学生学号:"))
        self.pushButton_9.setText(_translate("MainWindow", "确定"))
        self.pushButton_9.clicked.connect(self.delete_student)
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), _translate("MainWindow", "退学处理"))
        # 表三
        self.label_10.setText(_translate("MainWindow", "学号:"))
        self.label_11.setText(_translate("MainWindow", "课程号:"))
        self.pushButton_10.setText(_translate("MainWindow", "确定"))
        self.pushButton_10.clicked.connect(self.delete_course)
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_3), _translate("MainWindow", "退课处理"))
        # 表四
        self.label_12.setText(_translate("MainWindow", "休学学生学号:"))
        self.label_13.setText(_translate("MainWindow", "复学学生学号:"))
        self.pushButton_11.setText(_translate("MainWindow", "确定"))
        self.pushButton_11.clicked.connect(self.suspend_or_reback_student)
        self.pushButton_12.setText(_translate("MainWindow", "确定"))
        self.pushButton_12.clicked.connect(self.suspend_or_reback_student)
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_4), _translate("MainWindow", "休复学处理"))
        # 表五
        self.label_14.setText(_translate("MainWindow", "注册学生学号:"))
        self.pushButton_13.setText(_translate("MainWindow", "确定"))
        self.pushButton_13.clicked.connect(self.register_student)
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_5), _translate("MainWindow", "注册处理"))
        # 表六
        self.label_15.setText(_translate("MainWindow", "请输入新密码:"))
        self.label_old.setText(_translate("MainWindow", "请输入旧密码:"))
        self.pushButton_14.setText(_translate("MainWindow", "确定"))
        self.pushButton_14.clicked.connect(self.update_password)
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_6), _translate("MainWindow", "密码修改"))
        # 表七
        self.label_16.setText(_translate("MainWindow", "您确定要退出吗?"))
        self.pushButton_15.setText(_translate("MainWindow", "确定"))
        self.pushButton_15.clicked.connect(self.jwc_exit)
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_7), _translate("MainWindow", "退出"))

    def update_course(self):
        """
        实现课程录入的方法,会在屏幕上显示操作结果
        :return: None
        """
        course_cid = self.lineEdit.text()
        course_name = self.lineEdit_2.text()
        course_room = self.lineEdit_3.text()
        course_teacher = self.lineEdit_4.text()
        course_date = self.lineEdit_5.text()
        course_pre_cid = self.lineEdit_6.text()
        course_credit = self.lineEdit_7.text()
        course_note = self.lineEdit_8.text()
        course_done = self.lineEdit_delete.text()
        # 检测输入的数据是否符合规范
        self.label_one.setText("")
        if course_date[len(course_date) - 1:len(course_date)] != "/":  # 自动在末尾添加'/'
            course_date += "/"
        if course_date[len(course_date) - 1:len(course_date)] == "/":
            # 转换上课时间
            time_data = ''
            dict_data = {}
            counter = 0
            for data in course_date:
                if data != '/' and counter != len(course_date):
                    time_data += data
                    counter += 1
                else:
                    dict_data[time_data[0:2]] = time_data[2:]
                    time_data = ''
            str_data = json.dumps(dict_data)
            # 插入数据
            if course_done == "":
                self.label_one.setText("退课截止时间不能为空!")
            elif course_cid != "" and course_name != "":
                # 发送课程录入请求
                Main_program.sock.send("jwc_course_table_insert".encode())
                # 打包数据
                data_dict = {
                    "course_cid": course_cid,
                    "course_name": course_name,
                    "course_classroom": course_room,
                    "course_teacher": course_teacher,
                    "course_date": str_data,
                    "course_pre_cid": course_pre_cid,
                    "course_credit": course_credit,
                    "course_note": course_note,
                    "course_done": course_done
                }
                data_dict = json.dumps(data_dict)
                Main_program.sock.send(data_dict.encode())
                flag = Main_program.sock.recv(1024).decode()
                if flag == "TRUE":
                    self.label_one.setText("课程录入成功!")
                    self.lineEdit.setText("")
                    self.lineEdit_2.setText("")
                    self.lineEdit_3.setText("")
                    self.lineEdit_4.setText("")
                    self.lineEdit_5.setText("")
                    self.lineEdit_6.setText("")
                    self.lineEdit_7.setText("")
                    self.lineEdit_8.setText("")
                    self.lineEdit_delete.setText("")
                else:
                    self.label_one.setText("课程录入失败!")
            else:
                self.label_one.setText("课程编号或课程名不能为空!")
        else:
            self.label_one.setText("时间输入务必以'/'隔开以及结尾!")

    def delete_student(self):
        """
        用于实现修改学生的状态为退学状态,会删除学生所有信息,仅将部分信息备份,在屏幕上显示修改结果
        :return: None
        """
        self.pushButton_9.clicked.disconnect()
        student_sid = self.lineEdit_9.text()
        self.label_two.setText("")
        if student_sid == "":
            self.label_two.setText("学生学号不可为空!")
        else:
            # 发送学生退学处理请求
            Main_program.sock.send("jwc_student_table_delete".encode())
            time.sleep(0.1)
            data_dict = {
                "student_sid": student_sid
            }
            data_dict = json.dumps(data_dict)
            Main_program.sock.send(data_dict.encode())  # 发送学生学号
            flag = Main_program.sock.recv(1024).decode()
            if flag == "HAVE_DONE":
                self.label_two.setText("该学号已进行了退学处理!")
            elif flag == "NONE":
                self.label_two.setText("不存在该学号!")
            elif flag == "OK":
                self.label_two.setText("退学处理成功!")
            elif flag == "ERROR":
                self.label_two.setText("退学处理成功,但备份失败!")
            else:
                self.label_two.setText("退学处理失败!")
        self.pushButton_9.clicked.connect(self.delete_student)

    def delete_course(self):
        """
        用于处理学生退课,会向服务端发起退学学生指定课程的方法,会在屏幕上显示处理结果
        :return: None
        """
        self.pushButton_10.clicked.disconnect()
        student_sid = self.lineEdit_10.text()
        course_cid = self.lineEdit_11.text()
        self.label_three.setText("")
        if student_sid == "":
            self.label_three.setText("学生学号不可为空!")
        elif course_cid == "":
            self.label_three.setText("课程编号不可为空!")
        else:
            # 发起退课处理请求
            Main_program.sock.send("jwc_score_table_delete".encode())
            time.sleep(0.1)
            # 打包数据
            dict_data = {
                "student_sid": student_sid,
                "course_cid": course_cid
            }
            # 发送转字符串后的数据
            dict_data = json.dumps(dict_data)
            Main_program.sock.send(str(dict_data).encode())
            flag = Main_program.sock.recv(1024).decode()
            if flag == "NONE_THIS":
                self.label_three.setText("不存在该学号与课程号的组合!")
            elif flag == "NONE_SID":
                self.label_three.setText("不存在该学号!")
            elif flag == "OK":
                self.label_three.setText("退课处理成功!")
                self.lineEdit_10.setText("")
                self.lineEdit_11.setText("")
            else:
                self.label_three.setText("退课处理失败!")
        self.pushButton_10.clicked.connect(self.delete_course)

    def suspend_or_reback_student(self):
        """
        用于处理学生的休复学处理,当输入不为空点击按钮后,会向服务端发起休复学处理请求,用于修改学生的休复学状态,在屏幕上显示处理结果
        :return: None
        """
        self.pushButton_11.clicked.disconnect()
        self.pushButton_12.clicked.disconnect()
        sign_flag = False
        suspend_sid = self.lineEdit_12.text()
        reback_sid = self.lineEdit_13.text()
        self.label_four.setText("")
        self.label_four2.setText("")
        # 判断修改学生的休学状态
        if suspend_sid != "":
            sign_flag = True
            # 向服务端发起休复学处理
            Main_program.sock.send("jwc_sus_update".encode())
            time.sleep(0.1)
            # 打包数据
            dict_data = {
                "mode": "suspend",
                "student_sid": suspend_sid
            }
            dict_data = json.dumps(dict_data)
            # 发送数据
            Main_program.sock.send(dict_data.encode())
            flag = Main_program.sock.recv(1024).decode()
            # 判断处理结果
            if flag == "OK":
                self.label_four.setText("休学处理成功!")
                self.lineEdit_12.setText("")
            elif flag == "HAVE_DONE":
                self.label_four.setText("该学号已进行了休学处理!")
            else:
                self.label_four.setText("休学处理失败!")
        else:
            pass
            # self.label_four.setText("休学学号为空!")
        # 判断修改学生复学状态
        if reback_sid != "":
            sign_flag = True
            # 向服务端发起休复学处理
            Main_program.sock.send("jwc_sus_update".encode())
            time.sleep(0.1)
            # 打包数据
            dict_data = {
                "mode": "reback",
                "student_sid": reback_sid
            }
            dict_data = json.dumps(dict_data)
            # 发送数据
            Main_program.sock.send(dict_data.encode())
            flag = Main_program.sock.recv(1024).decode()
            # 判断处理结果
            if flag == "OK":
                self.label_four2.setText("复学处理成功!")
                self.lineEdit_13.setText("")
            elif flag == "HAVE_DONE":
                self.label_four2.setText("该学号无需进行复学处理!")
            else:
                self.label_four2.setText("复学处理失败!")
        else:
            pass
            # self.label_four.setText("复学学号为空!")
        if sign_flag is False:
            self.label_four.setText("没有任何输入!")
        self.pushButton_11.clicked.connect(self.suspend_or_reback_student)
        self.pushButton_12.clicked.connect(self.suspend_or_reback_student)

    def register_student(self):
        """
        用于学生注册处理,向服务端发起学生注册处理,服务端返回处理结果,在屏幕上显示注册处理结果
        :return: None
        """
        self.pushButton_13.clicked.disconnect()
        register_sid = self.lineEdit_14.text()
        self.label_five.setText("")
        if register_sid == "":
            self.label_five.setText("学生学号不可为空!")
        else:
            # 发起学生注册处理请求
            Main_program.sock.send("jwc_reg_update".encode())
            time.sleep(0.1)
            # 打包数据并发送
            data_dict = {
                "student_sid": register_sid
            }
            data_dict = json.dumps(data_dict)
            Main_program.sock.send(data_dict.encode())
            flag = Main_program.sock.recv(1024).decode()
            if flag == "OK":
                self.label_five.setText("注册处理成功!")
                self.lineEdit_14.setText("")
            elif flag == "HAVE_DONE":
                self.label_five.setText("该学号已注册!")
            elif flag == "FALSE":
                self.label_five.setText("不存在该学号!")
            else:
                self.label_five.setText("注册处理失败!")
        self.pushButton_13.clicked.connect(self.register_student)

    def update_password(self):
        self.pushButton_14.clicked.disconnect()
        new_pwd = self.lineEdit_15.text()
        old_pwd = self.lineEdit_old.text()
        self.label_six.setText("")
        if new_pwd == "":
            self.label_six.setText("新密码不可为空!")
        elif old_pwd == "":
            self.label_six.setText("原密码不可为空!")
        else:
            Main_program.sock.send("jwc_pwd_update".encode())
            time.sleep(0.1)
            data_dict = {
                "old_pwd": old_pwd,
                "new_pwd": new_pwd
            }
            data_dict = json.dumps(data_dict)
            Main_program.sock.send(data_dict.encode())
            flag = Main_program.sock.recv(1024).decode()
            if flag == "OK":
                self.label_six.setText("密码修改成功!")
                self.lineEdit_old.setText("")
                self.lineEdit_15.setText("")
            elif flag == "ERROR":
                self.label_six.setText("原密码错误!")
            else:
                self.label_six.setText("密码修改失败!")
        self.pushButton_14.clicked.connect(self.update_password)

    def jwc_exit(self):
        self.pushButton_15.clicked.disconnect()
        Main_program.sock.send("jwc_exit".encode())
        Main_program.sock.close()
        sys.exit()


class xy_window(object):
    """
    学院窗口的实现
    """
    # 数据字典列表
    score_data_dict_list = []  # 选课
    course_data_dict_list = []  # 课程
    student_data_dict_list = []  # 学生

    def __init__(self):
        super().__init__()
        self.type = "学院"  # 记录用户类型
        self.name = None  # 记录用户名
        self.pwd = None  # 记录用户密码

    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        # MainWindow.resize(640, 600)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.tabWidget = QtWidgets.QTabWidget(self.centralwidget)
        self.tabWidget.setGeometry(QtCore.QRect(20, 20, 900, 521))
        self.tabWidget.setObjectName("tabWidget")
        # 第一张表
        self.tab = QtWidgets.QWidget()
        self.tab.setObjectName("tab")
        self.label = QtWidgets.QLabel(self.tab)
        self.label.setGeometry(QtCore.QRect(60, 130, 100, 30))
        self.label.setObjectName("label")
        self.label_2 = QtWidgets.QLabel(self.tab)
        self.label_2.setGeometry(QtCore.QRect(60, 170, 100, 30))
        self.label_2.setObjectName("label_2")
        self.label_3 = QtWidgets.QLabel(self.tab)
        self.label_3.setGeometry(QtCore.QRect(60, 210, 100, 30))
        self.label_3.setObjectName("label_3")
        self.label_3_1 = QtWidgets.QLabel(self.tab)
        self.label_3_1.setGeometry(QtCore.QRect(60, 250, 100, 30))
        self.label_3_1.setObjectName("label_3_1")
        self.label_3_2 = QtWidgets.QLabel(self.tab)
        self.label_3_2.setGeometry(QtCore.QRect(60, 290, 100, 30))
        self.label_3_2.setObjectName("label_3_2")
        self.pushButton = QtWidgets.QPushButton(self.tab)
        self.pushButton.setGeometry(QtCore.QRect(60, 330, 80, 30))
        self.pushButton.setObjectName("pushButton")
        self.lineEdit = QtWidgets.QLineEdit(self.tab)
        self.lineEdit.setGeometry(QtCore.QRect(180, 130, 120, 30))
        self.lineEdit.setObjectName("lineEdit")
        self.lineEdit_2 = QtWidgets.QLineEdit(self.tab)
        self.lineEdit_2.setGeometry(QtCore.QRect(180, 170, 120, 30))
        self.lineEdit_2.setObjectName("lineEdit_2")
        self.lineEdit_3 = QtWidgets.QLineEdit(self.tab)
        self.lineEdit_3.setGeometry(QtCore.QRect(180, 210, 120, 30))
        self.lineEdit_3.setObjectName("lineEdit_3")
        self.lineEdit_3_1 = QtWidgets.QLineEdit(self.tab)
        self.lineEdit_3_1.setGeometry(QtCore.QRect(180, 250, 120, 30))
        self.lineEdit_3_1.setObjectName("lineEdit_3_1")
        self.lineEdit_3_2 = QtWidgets.QLineEdit(self.tab)
        self.lineEdit_3_2.setGeometry(QtCore.QRect(180, 290, 120, 30))
        self.lineEdit_3_2.setObjectName("lineEdit_3_2")
        self.label_one = QtWidgets.QLabel(self.tab)
        self.label_one.setGeometry(QtCore.QRect(60, 370, 200, 30))
        self.label_one.setObjectName("label_one")
        # 第二张表
        self.tabWidget.addTab(self.tab, "")
        self.tab_2 = QtWidgets.QWidget()
        self.tab_2.setObjectName("tab_2")
        self.tableWidget_3 = QtWidgets.QTableWidget(self.tab_2)
        self.tableWidget_3.setGeometry(QtCore.QRect(30, 30, 800, 400))
        self.tableWidget_3.setObjectName("tableWidget_3")
        self.tableWidget_3.setColumnCount(4)
        self.tableWidget_3.setRowCount(0)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget_3.setHorizontalHeaderItem(0, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget_3.setHorizontalHeaderItem(1, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget_3.setHorizontalHeaderItem(2, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget_3.setHorizontalHeaderItem(3, item)
        self.pushButton_update_choose_course = QtWidgets.QPushButton(self.tab_2)  # 增加更新数据按钮
        self.pushButton_update_choose_course.setGeometry(QtCore.QRect(30, 450, 100, 30))
        self.pushButton_update_choose_course.setObjectName("pushButton_update_choose_course")
        self.label_two = QtWidgets.QLabel(self.tab_2)  # 增加提示标签
        self.label_two.setGeometry(QtCore.QRect(150, 450, 250, 30))
        self.label_two.setObjectName("label_two")
        self.comboBox = QtWidgets.QComboBox(self.tab_2)  # 按条件查询组件
        self.comboBox.setGeometry(QtCore.QRect(400, 450, 100, 30))
        self.comboBox.setObjectName("comboBox")
        self.comboBox.addItem("")
        self.comboBox.addItem("")
        self.comboBox.addItem("")
        self.comboBox.addItem("")
        self.lineEdit_two_query = QtWidgets.QLineEdit(self.tab_2)
        self.lineEdit_two_query.setGeometry(QtCore.QRect(510, 450, 150, 30))
        self.lineEdit_two_query.setObjectName("lineEdit_two_query")
        self.pushButton_two_query = QtWidgets.QPushButton(self.tab_2)  # 增加更新数据按钮
        self.pushButton_two_query.setGeometry(QtCore.QRect(670, 450, 100, 30))
        self.pushButton_two_query.setObjectName("pushButton_two_query")
        # 第三张表
        self.tabWidget.addTab(self.tab_2, "")
        self.tab_3 = QtWidgets.QWidget()
        self.tab_3.setObjectName("tab_3")
        self.tableWidget_2 = QtWidgets.QTableWidget(self.tab_3)
        self.tableWidget_2.setGeometry(QtCore.QRect(30, 30, 800, 400))
        self.tableWidget_2.setObjectName("tableWidget_2")
        self.tableWidget_2.setColumnCount(9)
        self.tableWidget_2.setRowCount(0)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget_2.setHorizontalHeaderItem(0, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget_2.setHorizontalHeaderItem(1, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget_2.setHorizontalHeaderItem(2, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget_2.setHorizontalHeaderItem(3, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget_2.setHorizontalHeaderItem(4, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget_2.setHorizontalHeaderItem(5, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget_2.setHorizontalHeaderItem(6, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget_2.setHorizontalHeaderItem(7, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget_2.setHorizontalHeaderItem(8, item)
        self.pushButton_update_course_data = QtWidgets.QPushButton(self.tab_3)  # 增加更新数据按钮
        self.pushButton_update_course_data.setGeometry(QtCore.QRect(30, 450, 100, 30))
        self.pushButton_update_course_data.setObjectName("pushButton_update_course_data")
        self.label_three = QtWidgets.QLabel(self.tab_3)  # 增加提示标签
        self.label_three.setGeometry(QtCore.QRect(150, 450, 250, 30))
        self.label_three.setObjectName("label_three")
        self.comboBox_2 = QtWidgets.QComboBox(self.tab_3)  # 按条件查询组件
        self.comboBox_2.setGeometry(QtCore.QRect(400, 450, 100, 30))
        self.comboBox_2.setObjectName("comboBox_2")
        self.comboBox_2.addItem("")
        self.comboBox_2.addItem("")
        self.comboBox_2.addItem("")
        self.comboBox_2.addItem("")
        self.comboBox_2.addItem("")
        self.comboBox_2.addItem("")
        self.comboBox_2.addItem("")
        self.comboBox_2.addItem("")
        self.comboBox_2.addItem("")
        self.lineEdit_three_query = QtWidgets.QLineEdit(self.tab_3)
        self.lineEdit_three_query.setGeometry(QtCore.QRect(510, 450, 150, 30))
        self.lineEdit_three_query.setObjectName("lineEdit_three_query")
        self.pushButton_three_query = QtWidgets.QPushButton(self.tab_3)  # 增加更新数据按钮
        self.pushButton_three_query.setGeometry(QtCore.QRect(670, 450, 100, 30))
        self.pushButton_three_query.setObjectName("pushButton_three_query")
        # 第四张表
        self.tabWidget.addTab(self.tab_3, "")
        self.tab_4 = QtWidgets.QWidget()
        self.tab_4.setObjectName("tab_4")
        self.tableWidget = QtWidgets.QTableWidget(self.tab_4)
        self.tableWidget.setGeometry(QtCore.QRect(30, 30, 800, 400))
        self.tableWidget.setObjectName("tableWidget")
        self.tableWidget.setColumnCount(7)
        self.tableWidget.setRowCount(0)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(0, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(1, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(2, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(3, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(4, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(5, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(6, item)
        self.pushButton_update_student_data = QtWidgets.QPushButton(self.tab_4)  # 增加更新数据按钮
        self.pushButton_update_student_data.setGeometry(QtCore.QRect(30, 450, 100, 30))
        self.pushButton_update_student_data.setObjectName("pushButton_update_student_data")
        self.label_four = QtWidgets.QLabel(self.tab_4)  # 增加提示标签
        self.label_four.setGeometry(QtCore.QRect(150, 450, 250, 30))
        self.label_four.setObjectName("label_four")
        self.comboBox_3 = QtWidgets.QComboBox(self.tab_4)  # 按条件查询组件
        self.comboBox_3.setGeometry(QtCore.QRect(400, 450, 100, 30))
        self.comboBox_3.setObjectName("comboBox_3")
        self.comboBox_3.addItem("")
        self.comboBox_3.addItem("")
        self.comboBox_3.addItem("")
        self.comboBox_3.addItem("")
        self.comboBox_3.addItem("")
        self.comboBox_3.addItem("")
        self.comboBox_3.addItem("")
        self.lineEdit_four_query = QtWidgets.QLineEdit(self.tab_4)
        self.lineEdit_four_query.setGeometry(QtCore.QRect(510, 450, 150, 30))
        self.lineEdit_four_query.setObjectName("lineEdit_four_query")
        self.pushButton_four_query = QtWidgets.QPushButton(self.tab_4)  # 增加更新数据按钮
        self.pushButton_four_query.setGeometry(QtCore.QRect(670, 450, 100, 30))
        self.pushButton_four_query.setObjectName("pushButton_four_query")
        # 第五张表
        self.tabWidget.addTab(self.tab_4, "")
        self.tab_5 = QtWidgets.QWidget()
        self.tab_5.setObjectName("tab_5")
        self.label_4 = QtWidgets.QLabel(self.tab_5)
        self.label_4.setGeometry(QtCore.QRect(50, 100, 100, 30))
        self.label_4.setObjectName("label_4")
        self.label_5 = QtWidgets.QLabel(self.tab_5)
        self.label_5.setGeometry(QtCore.QRect(50, 140, 100, 30))
        self.label_5.setObjectName("label_5")
        self.label_6 = QtWidgets.QLabel(self.tab_5)
        self.label_6.setGeometry(QtCore.QRect(50, 180, 100, 30))
        self.label_6.setObjectName("label_6")
        self.pushButton_2 = QtWidgets.QPushButton(self.tab_5)
        self.pushButton_2.setGeometry(QtCore.QRect(50, 230, 80, 30))
        self.pushButton_2.setObjectName("pushButton_2")
        self.lineEdit_4 = QtWidgets.QLineEdit(self.tab_5)
        self.lineEdit_4.setGeometry(QtCore.QRect(170, 100, 120, 30))
        self.lineEdit_4.setObjectName("lineEdit_4")
        self.lineEdit_5 = QtWidgets.QLineEdit(self.tab_5)
        self.lineEdit_5.setGeometry(QtCore.QRect(170, 140, 120, 30))
        self.lineEdit_5.setObjectName("lineEdit_5")
        self.lineEdit_6 = QtWidgets.QLineEdit(self.tab_5)
        self.lineEdit_6.setGeometry(QtCore.QRect(170, 180, 120, 30))
        self.lineEdit_6.setObjectName("lineEdit_6")
        self.label_five = QtWidgets.QLabel(self.tab_5)
        self.label_five.setGeometry(QtCore.QRect(50, 270, 200, 30))
        self.label_five.setObjectName("label_five")
        # 第六张表
        self.tabWidget.addTab(self.tab_5, "")
        self.tab_6 = QtWidgets.QWidget()
        self.tab_6.setObjectName("tab_6")
        self.label_7 = QtWidgets.QLabel(self.tab_6)
        self.label_7.setGeometry(QtCore.QRect(30, 200, 150, 30))
        self.label_7.setObjectName("label_7")
        self.pushButton_3 = QtWidgets.QPushButton(self.tab_6)
        self.pushButton_3.setGeometry(QtCore.QRect(30, 250, 80, 30))
        self.pushButton_3.setObjectName("pushButton_3")
        self.lineEdit_7 = QtWidgets.QLineEdit(self.tab_6)
        self.lineEdit_7.setGeometry(QtCore.QRect(190, 200, 200, 30))
        self.lineEdit_7.setObjectName("lineEdit_7")
        self.label_six = QtWidgets.QLabel(self.tab_6)
        self.label_six.setGeometry(QtCore.QRect(30, 290, 200, 30))
        self.label_six.setObjectName("label_six")
        # 第七张表
        self.tabWidget.addTab(self.tab_6, "")
        self.tab_7 = QtWidgets.QWidget()
        self.tab_7.setObjectName("tab_7")
        self.label_8 = QtWidgets.QLabel(self.tab_7)
        self.label_8.setGeometry(QtCore.QRect(30, 230, 150, 30))
        self.label_8.setObjectName("label_8")
        self.pushButton_4 = QtWidgets.QPushButton(self.tab_7)
        self.pushButton_4.setGeometry(QtCore.QRect(200, 230, 80, 30))
        self.pushButton_4.setObjectName("pushButton_4")
        self.tabWidget.addTab(self.tab_7, "")
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 640, 22))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        self.tabWidget.setCurrentIndex(1)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        # MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        MainWindow.setWindowTitle("选课管理系统")
        MainWindow.resize(950, 600)
        # 表一
        self.label.setText(_translate("MainWindow", "学生学号:"))
        self.label_2.setText(_translate("MainWindow", "学生姓名:"))
        self.label_3.setText(_translate("MainWindow", "学生性别:"))
        self.label_3_1.setText(_translate("MainWindow", "学生年龄:"))
        self.label_3_2.setText(_translate("MainWindow", "学生籍贯:"))
        self.pushButton.setText(_translate("MainWindow", "保存"))
        self.pushButton.clicked.connect(self.student_data_insert)
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), _translate("MainWindow", "学生信息录入"))
        # 表二
        item = self.tableWidget_3.horizontalHeaderItem(0)
        item.setText(_translate("MainWindow", "SID"))
        item = self.tableWidget_3.horizontalHeaderItem(1)
        item.setText(_translate("MainWindow", "CID"))
        item = self.tableWidget_3.horizontalHeaderItem(2)
        item.setText(_translate("MainWindow", "SCORE"))
        item = self.tableWidget_3.horizontalHeaderItem(3)
        item.setText(_translate("MainWindow", "DELAPP"))
        self.pushButton_update_choose_course.setText(_translate("MainWindow", "查询所有"))
        self.pushButton_update_choose_course.clicked.connect(self.update_list_change_course)
        self.comboBox.setItemText(0, _translate("MainWindow", "SID"))  # 按条件查询
        self.comboBox.setItemText(1, _translate("MainWindow", "CID"))
        self.comboBox.setItemText(2, _translate("MainWindow", "SCORE"))
        self.comboBox.setItemText(3, _translate("MainWindow", "DELAPP"))
        self.pushButton_two_query.setText(_translate("MainWindow", "查询目标"))
        self.pushButton_two_query.clicked.connect(self.query_target_change_course)
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), _translate("MainWindow", "选课查询"))
        # 表三
        item = self.tableWidget_2.horizontalHeaderItem(0)
        item.setText(_translate("MainWindow", "CID"))
        item = self.tableWidget_2.horizontalHeaderItem(1)
        item.setText(_translate("MainWindow", "NAME"))
        item = self.tableWidget_2.horizontalHeaderItem(2)
        item.setText(_translate("MainWindow", "CLASSROOM"))
        item = self.tableWidget_2.horizontalHeaderItem(3)
        item.setText(_translate("MainWindow", "TEACHER"))
        item = self.tableWidget_2.horizontalHeaderItem(4)
        item.setText(_translate("MainWindow", "TIME"))
        item = self.tableWidget_2.horizontalHeaderItem(5)
        item.setText(_translate("MainWindow", "PRE_CID"))
        item = self.tableWidget_2.horizontalHeaderItem(6)
        item.setText(_translate("MainWindow", "CREDIT"))
        item = self.tableWidget_2.horizontalHeaderItem(7)
        item.setText(_translate("MainWindow", "NOTE"))
        item = self.tableWidget_2.horizontalHeaderItem(8)
        item.setText(_translate("MainWindow", "DONE_DATE"))
        self.pushButton_update_course_data.setText(_translate("MainWindow", "查询所有"))
        self.pushButton_update_course_data.clicked.connect(self.update_list_course_data)
        self.comboBox_2.setItemText(0, _translate("MainWindow", "CID"))  # 按条件查询
        self.comboBox_2.setItemText(1, _translate("MainWindow", "NAME"))
        self.comboBox_2.setItemText(2, _translate("MainWindow", "CLASSROOM"))
        self.comboBox_2.setItemText(3, _translate("MainWindow", "TEACHER"))
        self.comboBox_2.setItemText(4, _translate("MainWindow", "DATE"))
        self.comboBox_2.setItemText(5, _translate("MainWindow", "PRE_CID"))
        self.comboBox_2.setItemText(6, _translate("MainWindow", "CREDIT"))
        self.comboBox_2.setItemText(7, _translate("MainWindow", "NOTE"))
        self.comboBox_2.setItemText(8, _translate("MainWindow", "DONE_DATE"))
        self.pushButton_three_query.setText(_translate("MainWindow", "查询目标"))
        self.pushButton_three_query.clicked.connect(self.query_target_course_data)
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_3), _translate("MainWindow", "课程信息查询"))
        # 表四
        item = self.tableWidget.horizontalHeaderItem(0)
        item.setText(_translate("MainWindow", "SID"))
        item = self.tableWidget.horizontalHeaderItem(1)
        item.setText(_translate("MainWindow", "NAME"))
        item = self.tableWidget.horizontalHeaderItem(2)
        item.setText(_translate("MainWindow", "GENDER"))
        item = self.tableWidget.horizontalHeaderItem(3)
        item.setText(_translate("MainWindow", "AGE"))
        item = self.tableWidget.horizontalHeaderItem(4)
        item.setText(_translate("MainWindow", "ADDRESS"))
        item = self.tableWidget.horizontalHeaderItem(5)
        item.setText(_translate("MainWindow", "SUSPENDED"))
        item = self.tableWidget.horizontalHeaderItem(6)
        item.setText(_translate("MainWindow", "REGISTERED"))
        self.pushButton_update_student_data.setText(_translate("MainWindow", "查询所有"))
        self.pushButton_update_student_data.clicked.connect(self.update_list_student_data)
        self.comboBox_3.setItemText(0, _translate("MainWindow", "SID"))  # 按条件查询
        self.comboBox_3.setItemText(1, _translate("MainWindow", "NAME"))
        self.comboBox_3.setItemText(2, _translate("MainWindow", "GENDER"))
        self.comboBox_3.setItemText(3, _translate("MainWindow", "AGE"))
        self.comboBox_3.setItemText(4, _translate("MainWindow", "ADDRESS"))
        self.comboBox_3.setItemText(5, _translate("MainWindow", "SUS"))
        self.comboBox_3.setItemText(6, _translate("MainWindow", "REG"))
        self.pushButton_four_query.setText(_translate("MainWindow", "查询目标"))
        self.pushButton_four_query.clicked.connect(self.query_target_student_data)
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_4), _translate("MainWindow", "学生信息查询"))
        # 表五
        self.label_4.setText(_translate("MainWindow", "学生学号:"))
        self.label_5.setText(_translate("MainWindow", "课程号:"))
        self.label_6.setText(_translate("MainWindow", "课程成绩:"))
        self.pushButton_2.setText(_translate("MainWindow", "保存"))
        self.pushButton_2.clicked.connect(self.update_student_score)
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_5), _translate("MainWindow", "成绩录入"))
        # 表六
        self.label_7.setText(_translate("MainWindow", "请输入密码:"))
        self.pushButton_3.setText(_translate("MainWindow", "确定"))
        self.pushButton_3.clicked.connect(self.update_password)
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_6), _translate("MainWindow", "密码修改"))
        # 表七
        self.label_8.setText(_translate("MainWindow", "您确定要退出吗?"))
        self.pushButton_4.setText(_translate("MainWindow", "确定"))
        self.pushButton_4.clicked.connect(self.xy_exit)
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_7), _translate("MainWindow", "退出"))

    def student_data_insert(self):
        """
        实现录入学生信息的方法,点击按钮后,会自动进行对输入数据的简单判断,通过后向服务端该学生信息插入请求,并在屏幕上显示处理结果
        :return: None
        """
        self.pushButton.clicked.disconnect()
        student_sid = self.lineEdit.text()
        student_name = self.lineEdit_2.text()
        student_gender = self.lineEdit_3.text()
        student_age = self.lineEdit_3_1.text()
        student_address = self.lineEdit_3_2.text()
        if student_sid == "":
            self.label_one.setText("学生学号不可为空!")
        elif student_name == "":
            self.label_one.setText("学生姓名不可为空!")
        elif student_gender == "":
            self.label_one.setText("学生性别不可为空!")
        elif student_age == "":
            self.label_one.setText("学生年龄不可为空!")
        elif student_address == "":
            self.label_one.setText("学生籍贯不可为空!")
        elif str(student_age).isdigit() is False:
            self.label_one.setText("学生年龄需为数字!")
        else:
            self.label_one.setText("")
            # 向服务端发起请求
            Main_program.sock.send("xy_student_table_insert".encode())
            time.sleep(0.1)
            data_dict = {
                "student_sid": student_sid,
                "student_name": student_name,
                "student_gender": student_gender,
                "student_age": student_age,
                "student_address": student_address
            }
            data_dict = json.dumps(data_dict)
            Main_program.sock.send(data_dict.encode())
            # 判断服务端处理结果
            data = Main_program.sock.recv(1024).decode()
            if data == "OK":
                self.lineEdit.setText("")
                self.lineEdit_2.setText("")
                self.lineEdit_3.setText("")
                self.lineEdit_3_1.setText("")
                self.lineEdit_3_2.setText("")
                self.label_one.setText("学生信息录入成功!")
            elif data == "HAVE_DONE":
                self.label_one.setText("该学号信息已经录入过了!")
            else:
                self.label_one.setText("学生信息录入失败!")
        self.pushButton.clicked.connect(self.student_data_insert)

    def update_list_change_course(self):
        """
        用于实现点击查询按钮查询学生选课信息的方法,点击按钮后,向服务端尕其查询选课情况请求,随后服务端返回选课信息,在屏幕上显示响应结果
        :return: None
        """
        self.pushButton_update_choose_course.clicked.disconnect()
        # 清空列表中的数据
        self.tableWidget_3.setRowCount(0)
        # 向服务端发起请求
        Main_program.sock.send("xy_score_table_select".encode())
        num_data = int(Main_program.sock.recv(1024).decode())
        data_list = []
        xy_window.score_data_dict_list.clear()
        for _ in range(num_data):
            data = Main_program.sock.recv(1024).decode()
            data = json.loads(data)
            data_list.append(data)
            xy_window.score_data_dict_list.append(data)
        self.label_two.setText("")
        # 判断数据是否为空
        if data_list != []:
            # 设置data_list行4列
            self.tableWidget_3.setRowCount(len(data_list))
            self.tableWidget_3.setColumnCount(4)
            # 向列表中插入数据
            counter = 0
            for data in data_list:
                self.tableWidget_3.setItem(counter, 0, QTableWidgetItem(data['sid']))
                self.tableWidget_3.setItem(counter, 1, QTableWidgetItem(data['cid']))
                self.tableWidget_3.setItem(counter, 2, QTableWidgetItem(data['score']))
                self.tableWidget_3.setItem(counter, 3, QTableWidgetItem(str(data['delapp'])))
                counter += 1
            self.label_two.setText("查询成功!")
            # 设置列表不可编辑
            self.tableWidget_3.setEditTriggers(QAbstractItemView.NoEditTriggers)
        else:
            self.label_two.setText("无数据!")
        self.pushButton_update_choose_course.clicked.connect(self.update_list_change_course)

    def query_target_change_course(self):
        """
        实现在已查询数据列表中,按目标数据类型,搜索指定数据的方法,并在屏幕上显示搜索结果
        :return: None
        """
        self.pushButton_two_query.clicked.disconnect()
        target_type = self.comboBox.currentText().lower()
        target_data = self.lineEdit_two_query.text()
        self.label_two.setText("")
        if xy_window.score_data_dict_list == []:
            self.label_two.setText("请先点击‘查询所有’按钮!")
        elif target_data == "":
            self.label_two.setText("请输入数据!")
        else:
            target_list = []
            flag = False
            for i, data in enumerate(xy_window.score_data_dict_list):
                if data[f'{target_type}'] == target_data:
                    target_list.append(data)
                    flag = True
            # 清空列表中的数据
            self.tableWidget_3.setRowCount(0)
            if flag is True:
                # 设置data_list行4列
                self.tableWidget_3.setRowCount(len(target_list))
                self.tableWidget_3.setColumnCount(4)
                # 向列表中插入数据
                counter = 0
                for data in target_list:
                    self.tableWidget_3.setItem(counter, 0, QTableWidgetItem(data['sid']))
                    self.tableWidget_3.setItem(counter, 1, QTableWidgetItem(data['cid']))
                    self.tableWidget_3.setItem(counter, 2, QTableWidgetItem(data['score']))
                    self.tableWidget_3.setItem(counter, 3, QTableWidgetItem(str(data['delapp'])))
                    counter += 1
                self.label_two.setText("已搜索到目标!")
            else:
                self.label_two.setText("未能搜索到目标!")
        self.pushButton_two_query.clicked.connect(self.query_target_change_course)

    def update_list_course_data(self):
        """
        用于实现点击刷新按钮刷新选课信息的方法,在屏幕上显示响应结果
        :return: None
        """
        self.pushButton_update_course_data.clicked.disconnect()
        # 清空列表中的数据
        self.tableWidget_2.setRowCount(0)
        # 发起请求
        Main_program.sock.send("xy_course_table_select".encode())
        num_data = int(Main_program.sock.recv(1024).decode())
        data_list = []
        xy_window.course_data_dict_list.clear()
        for _ in range(num_data):
            data = Main_program.sock.recv(1024).decode()
            data = json.loads(data)
            data_list.append(data)
            xy_window.course_data_dict_list.append(data)
        self.label_three.setText("")
        # 判断数据是否为空
        if data_list != []:
            # 设置data_list行4列
            self.tableWidget_2.setRowCount(len(data_list))
            self.tableWidget_2.setColumnCount(9)
            # 向列表中插入数据
            counter = 0
            for data in data_list:
                self.tableWidget_2.setItem(counter, 0, QTableWidgetItem(data['cid']))
                self.tableWidget_2.setItem(counter, 1, QTableWidgetItem(data['name']))
                self.tableWidget_2.setItem(counter, 2, QTableWidgetItem(data['classroom']))
                self.tableWidget_2.setItem(counter, 3, QTableWidgetItem(data['teacher']))
                date_dict = Main_program.repair_to_dict(data['date'])
                date_dict = json.loads(date_dict)
                date_str = ""
                for time1, time2 in date_dict.items():
                    date_str += time1 + time2 + "/"
                self.tableWidget_2.setItem(counter, 4, QTableWidgetItem(date_str))
                self.tableWidget_2.setItem(counter, 5, QTableWidgetItem(data['pre_cid']))
                self.tableWidget_2.setItem(counter, 6, QTableWidgetItem(str(data['credit'])))
                self.tableWidget_2.setItem(counter, 7, QTableWidgetItem(data['note']))
                self.tableWidget_2.setItem(counter, 8, QTableWidgetItem(data['done_date']))
                counter += 1
            self.label_three.setText("查询成功!")
            # 设置列表不可编辑
            self.tableWidget_2.setEditTriggers(QAbstractItemView.NoEditTriggers)
        else:
            self.label_three.setText("无数据!")
        self.pushButton_update_course_data.clicked.connect(self.update_list_course_data)

    def query_target_course_data(self):
        """
        用于实现在已查询的数据列表中,搜索目标数据,并在屏幕上显示搜索结果
        :return: None
        """
        self.pushButton_three_query.clicked.disconnect()
        target_type = self.comboBox_2.currentText().lower()
        target_data = self.lineEdit_three_query.text()
        self.label_three.setText("")
        if xy_window.course_data_dict_list == []:
            self.label_three.setText("请先点击‘查询所有’按钮!")
        elif target_data == "":
            self.label_three.setText("请输入数据!")
        else:
            target_list = []
            flag = False
            for i, data in enumerate(xy_window.course_data_dict_list):
                if str(data[f'{target_type}']) == target_data:
                    target_list.append(data)
                    flag = True
            # 清空列表中的数据
            self.tableWidget_2.setRowCount(0)
            if flag is True:
                # 设置data_list行9列
                self.tableWidget_2.setRowCount(len(target_list))
                self.tableWidget_2.setColumnCount(9)
                # 向列表中插入数据
                counter = 0
                for data in target_list:
                    self.tableWidget_2.setItem(counter, 0, QTableWidgetItem(data['cid']))
                    self.tableWidget_2.setItem(counter, 1, QTableWidgetItem(data['name']))
                    self.tableWidget_2.setItem(counter, 2, QTableWidgetItem(data['classroom']))
                    self.tableWidget_2.setItem(counter, 3, QTableWidgetItem(data['teacher']))
                    date_dict = Main_program.repair_to_dict(data['date'])
                    date_dict = json.loads(date_dict)
                    date_str = ""
                    for time1, time2 in date_dict.items():
                        date_str += time1 + time2 + "/"
                    self.tableWidget_2.setItem(counter, 4, QTableWidgetItem(date_str))
                    self.tableWidget_2.setItem(counter, 5, QTableWidgetItem(data['pre_cid']))
                    self.tableWidget_2.setItem(counter, 6, QTableWidgetItem(str(data['credit'])))
                    self.tableWidget_2.setItem(counter, 7, QTableWidgetItem(data['note']))
                    self.tableWidget_2.setItem(counter, 8, QTableWidgetItem(data['done_date']))
                    counter += 1
                self.label_three.setText("已搜索到目标!")
            else:
                self.label_three.setText("未能搜索到目标!")
        self.pushButton_three_query.clicked.connect(self.query_target_course_data)

    def update_list_student_data(self):
        """
        用于实现点击刷新按钮刷新学生信息的方法,向服务端发起请求,随后服务端返回数据,并在屏幕上显示响应结果
        :return: None
        """
        self.pushButton_update_student_data.clicked.disconnect()
        # 清空列表中的数据
        self.tableWidget.setRowCount(0)
        # 向服务端发起请求
        Main_program.sock.send("xy_student_table_select".encode())
        num_data = int(Main_program.sock.recv(1024).decode())
        data_list = []
        xy_window.student_data_dict_list.clear()
        for _ in range(num_data):
            data = Main_program.sock.recv(1024).decode()
            data = json.loads(data)
            data_list.append(data)
            xy_window.student_data_dict_list.append(data)
        self.label_four.setText("")
        # 判断数据是否为空
        if data_list != ():
            # 设置data_list行7列
            self.tableWidget.setRowCount(len(data_list))
            self.tableWidget.setColumnCount(7)
            # 向列表中插入数据
            counter = 0
            for data in data_list:
                self.tableWidget.setItem(counter, 0, QTableWidgetItem(data['sid']))
                self.tableWidget.setItem(counter, 1, QTableWidgetItem(data['name']))
                self.tableWidget.setItem(counter, 2, QTableWidgetItem(data['gender']))
                self.tableWidget.setItem(counter, 3, QTableWidgetItem(str(data['age'])))
                self.tableWidget.setItem(counter, 4, QTableWidgetItem(data['address']))
                self.tableWidget.setItem(counter, 5, QTableWidgetItem(str(data['sus'])))
                self.tableWidget.setItem(counter, 6, QTableWidgetItem(str(data['reg'])))
                counter += 1
            self.label_four.setText("查询成功!")
            # 设置列表不可编辑
            self.tableWidget.setEditTriggers(QAbstractItemView.NoEditTriggers)
        else:
            self.label_four.setText("无数据!")
        self.pushButton_update_student_data.clicked.connect(self.update_list_student_data)

    def query_target_student_data(self):
        self.pushButton_four_query.clicked.disconnect()
        target_type = self.comboBox_3.currentText().lower()
        target_data = self.lineEdit_four_query.text()
        self.label_four.setText("")
        if xy_window.student_data_dict_list == []:
            self.label_four.setText("请先点击‘查询所有’按钮!")
        elif target_data == "":
            self.label_four.setText("请输入数据!")
        else:
            target_list = []
            flag = False
            for i, data in enumerate(xy_window.student_data_dict_list):
                if str(data[f'{target_type}']) == target_data:
                    target_list.append(data)
                    flag = True
            # 清空列表中的数据
            self.tableWidget.setRowCount(0)
            if flag is True:
                # 设置data_list行4列
                self.tableWidget.setRowCount(len(target_list))
                self.tableWidget.setColumnCount(7)
                # 向列表中插入数据
                counter = 0
                for data in target_list:
                    self.tableWidget.setItem(counter, 0, QTableWidgetItem(data['sid']))
                    self.tableWidget.setItem(counter, 1, QTableWidgetItem(data['name']))
                    self.tableWidget.setItem(counter, 2, QTableWidgetItem(data['gender']))
                    self.tableWidget.setItem(counter, 3, QTableWidgetItem(str(data['age'])))
                    self.tableWidget.setItem(counter, 4, QTableWidgetItem(data['address']))
                    self.tableWidget.setItem(counter, 5, QTableWidgetItem(str(data['sus'])))
                    self.tableWidget.setItem(counter, 6, QTableWidgetItem(str((data['reg']))))
                    counter += 1
                self.label_four.setText("已搜索到目标!")
            else:
                self.label_four.setText("未能搜索到目标!")
        self.pushButton_four_query.clicked.connect(self.query_target_student_data)

    def update_student_score(self):
        """
        用于实现学生成绩录入的方法,点击按钮后,向服务端发请求请,服务端回应,并在屏幕上显示录入结果
        :return: None
        """
        self.pushButton_2.clicked.disconnect()
        student_sid = self.lineEdit_4.text()
        course_cid = self.lineEdit_5.text()
        course_score = self.lineEdit_6.text()
        self.label_five.setText("")
        if student_sid == "":
            self.label_five.setText("学生学号不可为空!")
        elif course_cid == "":
            self.label_five.setText("课程编号不可为空!")
        elif course_score == "":
            self.label_five.setText("课程成绩不可为空!")
        elif str(course_score).isdigit() is False:
            self.label_five.setText("成绩只能为数字!")
        else:
            # 发起请求
            Main_program.sock.send("xy_score_table_update".encode())
            data_dict = {
                "student_sid": student_sid,
                "course_cid": course_cid,
                "course_score": course_score
            }
            data_dict = json.dumps(data_dict)
            Main_program.sock.send(data_dict.encode())
            flag = Main_program.sock.recv(1024).decode()
            if flag == "OK":
                self.lineEdit_4.setText("")
                self.lineEdit_5.setText("")
                self.lineEdit_6.setText("")
                self.label_five.setText("成绩录入成功!")
            elif flag == "NONE_SID":
                self.label_five.setText("不存在该学号!")
            elif flag == "NONE_CID":
                self.label_five.setText("不存在该课程号")
            elif flag == "NONE_THIS":
                self.label_five.setText("该学号未选择对应的课程")
            elif flag == "HAVE_DONE":
                self.label_five.setText("成绩已经录入过了!")
            else:
                self.label_five.setText("成绩录入失败!")
        self.pushButton_2.clicked.connect(self.update_student_score)

    def update_password(self):
        """
        用于实现用户修改密码的方法,在屏幕上显示修改结果
        :return: None
        """
        self.pushButton_3.clicked.disconnect()
        new_pwd = self.lineEdit_7.text()
        self.label_six.setText("")
        if new_pwd == "":
            self.label_six.setText("新密码不可为空!")
        else:
            # 发起请求
            Main_program.sock.send("xy_pwd_update".encode())
            time.sleep(0.1)
            data_dict = {
                "new_pwd": new_pwd
            }
            data_dict = json.dumps(data_dict)
            Main_program.sock.send(data_dict.encode())
            flag = Main_program.sock.recv(1024).decode()
            if flag == "OK":
                self.label_six.setText("密码修改成功!")
                self.lineEdit_7.setText("")
            else:
                self.label_six.setText("密码修改失败!")
        self.pushButton_3.clicked.connect(self.update_password)

    def xy_exit(self):
        Main_program.sock.send("xy_exit".encode())
        Main_program.sock.close()
        sys.exit()


class student_window(object):
    """
    学生窗口的实现
    """
    score_data_dict_list = []  # 选课

    def __init__(self):
        super().__init__()
        self.type = "学生"  # 记录用户类型
        self.name = None  # 记录用户名
        self.pwd = None  # 记录用户密码

    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        # MainWindow.resize(642, 600)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.tabWidget = QtWidgets.QTabWidget(self.centralwidget)
        self.tabWidget.setGeometry(QtCore.QRect(20, 30, 800, 500))
        self.tabWidget.setObjectName("tabWidget")
        # 第一张表
        self.tab = QtWidgets.QWidget()
        self.tab.setObjectName("tab")
        self.label = QtWidgets.QLabel(self.tab)
        self.label.setGeometry(QtCore.QRect(50, 200, 100, 30))
        self.label.setObjectName("label")
        self.lineEdit = QtWidgets.QLineEdit(self.tab)
        self.lineEdit.setGeometry(QtCore.QRect(160, 200, 120, 30))
        self.lineEdit.setObjectName("lineEdit")
        self.pushButton = QtWidgets.QPushButton(self.tab)
        self.pushButton.setGeometry(QtCore.QRect(50, 240, 80, 30))
        self.pushButton.setObjectName("pushButton")
        self.label_one = QtWidgets.QLabel(self.tab)
        self.label_one.setGeometry(QtCore.QRect(50, 280, 300, 30))
        self.label_one.setObjectName("label_one")
        # 第二张表
        self.tabWidget.addTab(self.tab, "")
        self.tab_2 = QtWidgets.QWidget()
        self.tab_2.setObjectName("tab_2")
        self.tableWidget = QtWidgets.QTableWidget(self.tab_2)
        self.tableWidget.setGeometry(QtCore.QRect(30, 30, 700, 380))
        self.tableWidget.setObjectName("tableWidget")
        self.tableWidget.setColumnCount(4)
        self.tableWidget.setRowCount(0)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(0, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(1, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(2, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(3, item)
        # self.tableWidget.resizeColumnsToContents()  # 设置表格宽度自适应内容
        self.pushButton_update = QtWidgets.QPushButton(self.tab_2)  # 设置刷新数据内容按钮
        self.pushButton_update.setGeometry(QtCore.QRect(30, 430, 100, 30))
        self.pushButton_update.setObjectName("pushButton_update")
        self.label_two = QtWidgets.QLabel(self.tab_2)  # 增加提示标签
        self.label_two.setGeometry(QtCore.QRect(140, 430, 225, 30))
        self.label_two.setObjectName("label_two")
        self.comboBox = QtWidgets.QComboBox(self.tab_2)  # 按条件查询组件
        self.comboBox.setGeometry(QtCore.QRect(370, 430, 100, 30))
        self.comboBox.setObjectName("comboBox")
        self.comboBox.addItem("")
        self.comboBox.addItem("")
        self.comboBox.addItem("")
        self.comboBox.addItem("")
        self.lineEdit_two_query = QtWidgets.QLineEdit(self.tab_2)
        self.lineEdit_two_query.setGeometry(QtCore.QRect(480, 430, 150, 30))
        self.lineEdit_two_query.setObjectName("lineEdit_two_query")
        self.pushButton_two_query = QtWidgets.QPushButton(self.tab_2)  # 增加更新数据按钮
        self.pushButton_two_query.setGeometry(QtCore.QRect(640, 430, 100, 30))
        self.pushButton_two_query.setObjectName("pushButton_two_query")
        # 第三张表
        self.tabWidget.addTab(self.tab_2, "")
        self.tab_3 = QtWidgets.QWidget()
        self.tab_3.setObjectName("tab_3")
        self.label_2 = QtWidgets.QLabel(self.tab_3)
        self.label_2.setGeometry(QtCore.QRect(50, 200, 120, 30))
        self.label_2.setObjectName("label_2")
        self.lineEdit_2 = QtWidgets.QLineEdit(self.tab_3)
        self.lineEdit_2.setGeometry(QtCore.QRect(180, 200, 120, 30))
        self.lineEdit_2.setObjectName("lineEdit_2")
        self.pushButton_2 = QtWidgets.QPushButton(self.tab_3)
        self.pushButton_2.setGeometry(QtCore.QRect(50, 240, 80, 30))
        self.pushButton_2.setObjectName("pushButton_2")
        self.label_three = QtWidgets.QLabel(self.tab_3)
        self.label_three.setGeometry(QtCore.QRect(50, 280, 200, 30))
        self.label_three.setObjectName("label_three")
        # 第四张表
        self.tabWidget.addTab(self.tab_3, "")
        self.tab_4 = QtWidgets.QWidget()
        self.tab_4.setObjectName("tab_4")
        self.label_3 = QtWidgets.QLabel(self.tab_4)
        self.label_3.setGeometry(QtCore.QRect(50, 200, 120, 30))
        self.label_3.setObjectName("label_3")
        self.lineEdit_3 = QtWidgets.QLineEdit(self.tab_4)
        self.lineEdit_3.setGeometry(QtCore.QRect(180, 200, 160, 30))
        self.lineEdit_3.setObjectName("lineEdit_3")
        self.pushButton_3 = QtWidgets.QPushButton(self.tab_4)
        self.pushButton_3.setGeometry(QtCore.QRect(50, 240, 80, 30))
        self.pushButton_3.setObjectName("pushButton_3")
        self.label_four = QtWidgets.QLabel(self.tab_4)
        self.label_four.setGeometry(QtCore.QRect(50, 280, 200, 30))
        self.label_four.setObjectName("label_four")
        # 第五张表
        self.tabWidget.addTab(self.tab_4, "")
        self.tab_5 = QtWidgets.QWidget()
        self.tab_5.setObjectName("tab_5")
        self.label_4 = QtWidgets.QLabel(self.tab_5)
        self.label_4.setGeometry(QtCore.QRect(50, 185, 150, 30))
        self.label_4.setObjectName("label_4")
        self.pushButton_4 = QtWidgets.QPushButton(self.tab_5)
        self.pushButton_4.setGeometry(QtCore.QRect(210, 185, 80, 30))
        self.pushButton_4.setObjectName("pushButton_4")
        self.tabWidget.addTab(self.tab_5, "")
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 642, 22))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        self.tabWidget.setCurrentIndex(3)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        # MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        MainWindow.setWindowTitle("选课管理系统")
        MainWindow.resize(900, 600)
        self.label.setText(_translate("MainWindow", "课程号:"))
        self.pushButton.setText(_translate("MainWindow", "确定"))
        self.pushButton.clicked.connect(self.choose_course)
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), _translate("MainWindow", "选课"))
        item = self.tableWidget.horizontalHeaderItem(0)
        item.setText(_translate("MainWindow", "SID"))
        item = self.tableWidget.horizontalHeaderItem(1)
        item.setText(_translate("MainWindow", "CID"))
        item = self.tableWidget.horizontalHeaderItem(2)
        item.setText(_translate("MainWindow", "SCORE"))
        item = self.tableWidget.horizontalHeaderItem(3)
        item.setText(_translate("MainWindow", "DELAPP"))
        self.pushButton_update.setText(_translate("MainWindow", "查询所有"))
        self.pushButton_update.clicked.connect(self.update_course)
        self.comboBox.setItemText(0, _translate("MainWindow", "SID"))  # 按条件查询
        self.comboBox.setItemText(1, _translate("MainWindow", "CID"))
        self.comboBox.setItemText(2, _translate("MainWindow", "SCORE"))
        self.comboBox.setItemText(3, _translate("MainWindow", "DELAPP"))
        self.pushButton_two_query.setText(_translate("MainWindow", "查询目标"))
        self.pushButton_two_query.clicked.connect(self.query_target_course)
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), _translate("MainWindow", "选课查询"))
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), _translate("MainWindow", "选课查询"))
        #
        self.label_2.setText(_translate("MainWindow", "退课的课程号:"))
        self.pushButton_2.setText(_translate("MainWindow", "确定"))
        self.pushButton_2.clicked.connect(self.delete_course)
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_3), _translate("MainWindow", "退课请求"))
        self.label_3.setText(_translate("MainWindow", "请输入密码:"))
        self.pushButton_3.setText(_translate("MainWindow", "确定"))
        self.pushButton_3.clicked.connect(self.update_password)
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_4), _translate("MainWindow", "密码修改"))
        self.label_4.setText(_translate("MainWindow", "您确定要退出吗?"))
        self.pushButton_4.setText(_translate("MainWindow", "确定"))
        self.pushButton_4.clicked.connect(self.student_exit)
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_5), _translate("MainWindow", "退出"))

    def choose_course(self):
        """
        用于实现学生选课的方法,向服务端发送请求,同时检测学生的选课时间是否存在时间冲突,并在屏幕上显示选课结果
        :return: None
        """
        self.pushButton.disconnect()
        course_cid = self.lineEdit.text()
        self.label_one.setText("")
        if course_cid == "":
            self.label_one.setText("课程号不能为空!")
        else:
            Main_program.sock.send("stu_score_table_insert".encode())
            time.sleep(0.1)
            data_dict = {
                "course_cid": course_cid
            }
            data_dict = json.dumps(data_dict)
            Main_program.sock.send(data_dict.encode())
            flag = Main_program.sock.recv(1024).decode()
            if flag == "OK":
                self.lineEdit.setText("")
                self.label_one.setText("选课成功!")
            elif flag == "NONE_CID":
                self.label_one.setText("没有该课程号!")
            elif flag == "HAVE_DONE":
                self.label_one.setText("该课程号已经选择过了!")
            elif flag == "NONE_PRECID":
                self.label_one.setText("缺少该课程的先修课!")
            elif flag == "HAVE_FULL_CREDITS":
                self.label_one.setText("选修的课程分数已满18分!")
            elif flag == "TIME_ERROR":
                self.label_one.setText("选课时间存在冲突!")
            elif flag == "NO_REGISTER":
                self.label_one.setText("学号尚未注册,无法选课!")
            else:
                self.label_one.setText("选课失败!")
        self.pushButton.clicked.connect(self.choose_course)

    def update_course(self):
        """
        用于实现点击按钮更新学生选课信息列表的方法,在屏幕上显示响应结果
        :return: None
        """
        self.pushButton_update.clicked.disconnect()
        # 清空列表中的数据
        self.tableWidget.setRowCount(0)
        # 向服务端发起请求
        Main_program.sock.send("stu_score_table_update".encode())
        num_data = Main_program.sock.recv(1024).decode()
        data_list = []
        student_window.score_data_dict_list.clear()
        if num_data != "0":
            data = Main_program.sock.recv(1024).decode()
            data = json.loads(data)
            data_list.append(data)
            student_window.score_data_dict_list.append(data)
        self.label_two.setText("")
        # 判断数据是否为空
        if data_list != []:
            # 设置data_list行4列
            self.tableWidget.setRowCount(len(data_list))
            self.tableWidget.setColumnCount(4)
            # 向列表中插入数据
            counter = 0
            for data in data_list:
                self.tableWidget.setItem(counter, 0, QTableWidgetItem(data['sid']))
                self.tableWidget.setItem(counter, 1, QTableWidgetItem(data['cid']))
                self.tableWidget.setItem(counter, 2, QTableWidgetItem(data['score']))
                self.tableWidget.setItem(counter, 3, QTableWidgetItem(data['delapp']))
                counter += 1
            self.label_two.setText("查询成功!")
            # 设置列表不可编辑
            self.tableWidget.setEditTriggers(QAbstractItemView.NoEditTriggers)
        else:
            self.label_two.setText("无数据!")
        self.pushButton_update.clicked.connect(self.update_course)

    def query_target_course(self):
        self.pushButton_two_query.clicked.disconnect()
        target_type = self.comboBox.currentText().lower()
        target_data = self.lineEdit_two_query.text()
        self.label_two.setText("")
        if student_window.score_data_dict_list == []:
            self.label_two.setText("请先点击‘查询所有’按钮!")
        elif target_data == "":
            self.label_two.setText("请输入数据!")
        else:
            target_list = []
            flag = False
            for i, data in enumerate(student_window.score_data_dict_list):
                if data[f'{target_type}'] == target_data:
                    target_list.append(data)
                    flag = True
            # 清空列表中的数据
            self.tableWidget.setRowCount(0)
            if flag is True:
                # 设置data_list行4列
                self.tableWidget.setRowCount(len(target_list))
                self.tableWidget.setColumnCount(4)
                # 向列表中插入数据
                counter = 0
                for data in target_list:
                    self.tableWidget.setItem(counter, 0, QTableWidgetItem(data['sid']))
                    self.tableWidget.setItem(counter, 1, QTableWidgetItem(data['cid']))
                    self.tableWidget.setItem(counter, 2, QTableWidgetItem(data['score']))
                    self.tableWidget.setItem(counter, 3, QTableWidgetItem(str(data['delapp'])))
                    counter += 1
                self.label_two.setText("已搜索到目标!")
            else:
                self.label_two.setText("未能搜索到目标!")
        self.pushButton_two_query.clicked.connect(self.query_target_course)

    def delete_course(self):
        """
        用于实现学生退课的方法,点击按钮后,向服务端发起请求,判断当前课程是否可以退课,服务端返回状况,并在屏幕上显示处理结果
        :return: None
        """
        self.pushButton_2.clicked.disconnect()
        course_cid = self.lineEdit_2.text()
        self.label_three.setText("")
        if course_cid == "":
            self.label_three.setText("课程号不能为空!")
        else:
            # 发起退课请求
            Main_program.sock.send("stu_score_table_delete".encode())
            time.sleep(0.1)
            data_dict = {
                "course_cid": course_cid
            }
            data_dict = json.dumps(data_dict)
            Main_program.sock.send(data_dict.encode())
            # 判断学生是否有该课程
            flag = Main_program.sock.recv(1024).decode()
            if flag == "OK":
                self.label_three.setText("退课成功")
            elif flag == "NONE_CID":
                self.label_three.setText("无效的课程号!")
            elif flag == "APPLY_DELETE_TRUE":
                self.label_three.setText("课程已开课,申请退课中...")
            elif flag == "APPLY_DELETE_FALSE":
                self.label_three.setText("课程已开课,申请退课失败!")
            elif flag == "DENY_DELETE":
                self.label_three.setText("已有成绩,无法退课!")
            else:
                self.label_three.setText("退课失败!")
        self.pushButton_2.clicked.connect(self.delete_course)

    def update_password(self):
        """
        用于实现用户修改密码的方法,向服务端发起请求,服务端返回状态,并在屏幕上显示修改结果
        :return: None
        """
        self.pushButton_3.clicked.disconnect()
        new_pwd = self.lineEdit_3.text()
        self.label_four.setText("")
        if new_pwd == "":
            self.label_four.setText("新密码不可为空!")
        else:
            # 向服务端发起请求
            Main_program.sock.send("stu_pwd_update".encode())
            time.sleep(0.1)
            data_dict = {
                "new_pwd": new_pwd
            }
            data_dict = json.dumps(data_dict)
            Main_program.sock.send(data_dict.encode())
            flag = Main_program.sock.recv(1024).decode()
            if flag == "OK":
                self.label_four.setText("密码修改成功!")
                self.lineEdit_3.setText("")
            else:
                self.label_four.setText("密码修改失败!")
        self.pushButton_3.clicked.connect(self.update_password)

    def student_exit(self):
        self.pushButton_4.clicked.disconnect()
        Main_program.sock.send("stu_exit".encode())
        Main_program.sock.close()
        sys.exit()


class Connect_program(object):
    """
    用于实现客户端与服务端进行通信的类
    """
    def __init__(self):
        super().__init__()

    @staticmethod
    def client_start(name, pwd, mode):
        """
        用于实现客户端与服务端验证用户身份的方法,验证成功后会启用永真线程,返回判断结果
        :param name: 用户名
        :param pwd: 用户密码
        :param mode: 用户类型
        :return: True/False
        """
        pass_flag = False
        try:
            # 尝试进行连接
            Main_program.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            Main_program.sock.connect(('127.0.0.1', 8000))
            # 发送用户类型
            Main_program.sock.send(mode.encode())
            time.sleep(0.1)
            # 发送用户名
            Main_program.sock.send(name.encode())
            flag = Main_program.sock.recv(1024).decode()
            if flag == 'TRUE':
                num = Main_program.sock.recv(1024).decode()
                num = int(pysm4.decrypt_ecb(num, pwd))
                num += 1
                Main_program.sock.send(str(num).encode())
                flag = Main_program.sock.recv(1024).decode()
                if flag == 'TRUE':
                    pass_flag = True
        except ConnectionRefusedError:
            # print("\033[91m 连接超时! \033[0m")
            pass
        except ValueError:
            # print("\033[91m 解密异常 \033[0m")
            pass
            Main_program.sock.send("ERROR".encode())
        finally:
            if pass_flag is True:
                return True
            else:
                Main_program.sock.close()
                return False


if __name__ == "__main__":
    os.environ['QT_QPA_PLATFORM_PLUGIN_PATH'] = ""  # 这里需要修改为自己QT的plugins的路径
    app = QApplication(sys.argv)

    window1 = QMainWindow()

    program = Main_program(window1)

    window1.show()

    sys.exit(app.exec_())

七,总结

通过以上的代码修改步骤,代码应该就可以运行了。

这是自己数据库专题训练的结课作业,代码浅陋,可能会有些报错,望见谅。

第一篇博客,难免有所疏漏,希望对各位有所帮助。

  • 27
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值