首页 > 数据库 >软件设计模式课程设计---Python实现学生信息管理系统(MySQL数据库+前端可视化)

软件设计模式课程设计---Python实现学生信息管理系统(MySQL数据库+前端可视化)

时间:2025-01-05 14:31:23浏览次数:3  
标签:课程设计 name Python self --- tk student ._ def

效果图:

代码目录:

代码:

main.py

import tkinter as tk
from tkinter import messagebox
from student_manager import StudentManager
from observer import StudentObserver
from factory import StudentFactory
from strategy import SortByName, SortByGrade
from proxy import StudentProxy
from command import AddStudentCommand, RemoveStudentCommand
from DatabaseConnection import DatabaseConnection


class StudentApp:
    def __init__(self, root):
        self.root = root
        self.root.title("学生信息管理系统")
        self.root.geometry("600x600")

        screenwidth = self.root.winfo_screenwidth()
        screenheight = self.root.winfo_screenheight()
        alignstr = '%dx%d+%d+%d' % (600, 600, (screenwidth - 600) / 2, (screenheight - 600) / 2)
        self.root.geometry(alignstr)

        self.root.resizable(False, False)  # 禁止调整窗口大小

        # 初始化学生管理器和观察者
        self.student_manager = StudentManager()
        self.student_observer = StudentObserver()
        self.student_manager.observers.append(self.student_observer)

        # 学生列表框,显示学生
        self.student_listbox_label = tk.Label(root, text="学生列表", font=("Arial", 14))
        self.student_listbox_label.pack(pady=10)

        # 表头区域(姓名和学号)
        self.header_frame = tk.Frame(root)
        self.header_frame.pack(padx=10, pady=5)

        # Adjust the padx to align headers with the listbox content
        self.name_header = tk.Label(self.header_frame, text="姓名", width=15, anchor="w", font=("Arial", 12, "bold"))
        self.name_header.grid(row=0, column=0, padx=10, pady=5)

        self.id_header = tk.Label(self.header_frame, text="学号", width=20, anchor="w", font=("Arial", 12, "bold"))
        self.id_header.grid(row=0, column=1, padx=5, pady=5)

        # 学生列表框,显示学生
        self.student_listbox = tk.Listbox(root, width=40, height=10, selectmode=tk.SINGLE, font=("Arial", 12))
        self.student_listbox.pack(padx=10, pady=10)

        # 输入框区域
        self.input_frame = tk.Frame(root)
        self.input_frame.pack(pady=10)

        # 学生姓名输入框
        self.name_label = tk.Label(self.input_frame, text="姓名:", width=20, anchor="w", font=("Arial", 12))
        self.name_label.grid(row=0, column=0, padx=10, pady=5)
        self.name_entry = tk.Entry(self.input_frame, width=30, font=("Arial", 12))
        self.name_entry.grid(row=0, column=1, padx=10, pady=5)

        # 学生学号输入框
        self.student_id_label = tk.Label(self.input_frame, text="学号:", width=20, anchor="w", font=("Arial", 12))
        self.student_id_label.grid(row=1, column=0, padx=10, pady=5)
        self.student_id_entry = tk.Entry(self.input_frame, width=30, font=("Arial", 12))
        self.student_id_entry.grid(row=1, column=1, padx=10, pady=5)

        # 查看学生姓名输入框
        self.view_name_label = tk.Label(self.input_frame, text="查看信息(姓名):", width=20, anchor="w",
                                        font=("Arial", 12))
        self.view_name_label.grid(row=2, column=0, padx=10, pady=5)
        self.view_name_entry = tk.Entry(self.input_frame, width=30, font=("Arial", 12))
        self.view_name_entry.grid(row=2, column=1, padx=10, pady=5)

        # 按钮区域
        self.button_frame = tk.Frame(root)
        self.button_frame.pack(pady=10)

        # 添加学生按钮
        self.add_button = tk.Button(self.button_frame, text="添加学生", width=20, bg="lightgreen",
                                    font=("Arial", 12), command=self.add_student)
        self.add_button.grid(row=0, column=0, padx=10, pady=5)

        # 删除学生按钮
        self.remove_button = tk.Button(self.button_frame, text="移除学生", width=20, bg="lightcoral",
                                       font=("Arial", 12), command=self.remove_student)
        self.remove_button.grid(row=0, column=1, padx=10, pady=5)

        # 排序按钮
        self.sort_button = tk.Button(self.button_frame, text="排序(按姓名)", width=20, bg="lightblue",
                                     font=("Arial", 12), command=self.sort_by_name)
        self.sort_button.grid(row=1, column=0, padx=10, pady=5)

        self.sort_grade_button = tk.Button(self.button_frame, text="排序(按学号)", width=20, bg="lightblue",
                                           font=("Arial", 12), command=self.sort_by_grade)
        self.sort_grade_button.grid(row=1, column=1, padx=10, pady=5)

        # 查看学生按钮
        self.view_button = tk.Button(self.button_frame, text="查看", width=20, bg="lightyellow",
                                     font=("Arial", 12), command=self.view_student)
        self.view_button.grid(row=2, column=0, columnspan=2, pady=5)

    def add_student(self):
        name = self.name_entry.get()
        student_id = self.student_id_entry.get()
        if not name or not student_id:
            messagebox.showwarning("错误!", "请同时输入学号和姓名")
            return
        student = StudentFactory.create_student(name, student_id)
        add_command = AddStudentCommand(self.student_manager, student)
        add_command.execute()
        self.update_student_list()

    def remove_student(self):
        selected_student_index = self.student_listbox.curselection()
        if not selected_student_index:
            messagebox.showwarning("错误!", "请选择要移除的学生")
            return

        student = self.student_manager.get_all_students()[selected_student_index[0]]
        remove_command = RemoveStudentCommand(self.student_manager, student)
        remove_command.execute()
        self.update_student_list()

    def sort_by_name(self):
        strategy = SortByName()
        self.student_manager.students = strategy.sort(self.student_manager.students)
        self.update_student_list()

    def sort_by_grade(self):
        strategy = SortByGrade()
        self.student_manager.students = strategy.sort(self.student_manager.students)
        self.update_student_list()

    def update_student_list(self):
        # 清空现有列表内容
        self.student_listbox.delete(0, tk.END)

        # 更新列表内容:每一行显示 "姓名       学号"(增加间隔)
        for student in self.student_manager.get_all_students():
            display_text = f"{student.name:<35} {student.student_id}"  # 增加空格以增加间隔
            self.student_listbox.insert(tk.END, display_text)

    def view_student(self):
        # 获取输入框中的学生姓名
        student_name = self.view_name_entry.get().strip()
        if not student_name:
            messagebox.showwarning("错误!", "请输入学生姓名")
            return

        # 在学生列表中查找对应学生
        student_found = None
        for student in self.student_manager.get_all_students():
            if student.name == student_name:
                student_found = student
                break

        if not student_found:
            messagebox.showwarning("未查找到学生", f"No student found with name: {student_name}")
            return

        # 如果找到学生,通过代理类查看其信息
        proxy = StudentProxy(student_found)
        proxy.grant_permission()
        student_info = proxy.get_student_info()
        messagebox.showinfo("学生信息", student_info)
if __name__ == "__main__":
    root = tk.Tk()
    app = StudentApp(root)
    root.mainloop()
    db1 = DatabaseConnection()
    db2 = DatabaseConnection()

    print(db1 is db2)  # 输出: True,表示db1和db2是同一个实例
    print(db1._connection)  # 输出: "Database Connection Established"



studentmanage.py:
 

# student_manager.py
import DatabaseConnection
class StudentManager:
    def __init__(self):
        self.students = []
        self.observers = []

    def add_student(self, student):
        self.students.append(student)
        self.notify(f"Student {student.name} added.")

    def remove_student(self, student):
        self.students.remove(student)
        self.notify(f"Student {student.name} removed.")

    def notify(self, message):
        for observer in self.observers:
            observer.update(message)

    def get_all_students(self):
        return self.students
    def DataConnect(self):
        db1 = DatabaseConnection()
        connection = db1.connect(host='localhost', user='root', password='', database='studentmanager')
        return connection
    # 查询
    def SelectFunction(self,sql):
        connection =StudentManager.DataConnect()
        cur = connection.cursor()  # 建立游标
        try:
            cur.execute(sql)
            result=cur.fetchall()
        except Exception as e:
            connection.rollback()  #回滚
        finally:
            cur.close()
            connection.close()
        return result

    # 封装更改数据库操作
    def change_db(sql):
        conn = StudentManager.DataConnect()  # 获取连接
        cur = conn.cursor()  # 建立游标
        try:
            cur.execute(sql)  # 执行sql
            conn.commit()  # 提交更改
        except Exception as e:
            conn.rollback()  # 回滚
        finally:
            cur.close()  # 关闭游标
            conn.close()  # 关闭连接4
    def add_user(name, id):
        sql = "insert into user (name, id) values ('{}','{}')".format(name, id)
        StudentManager.change_db(sql)

    def del_user(name):
        sql = "delete from user where name='{}'".format(name)
        StudentManager.change_db(sql)

command.py:


class Command:
    def execute(self):
        pass


class AddStudentCommand(Command):
    def __init__(self, student_manager, student):
        self._student_manager = student_manager
        self._student = student

    def execute(self):
        self._student_manager.add_student(self._student)


class RemoveStudentCommand(Command):
    def __init__(self, student_manager, student):
        self._student_manager = student_manager
        self._student = student

    def execute(self):
        self._student_manager.remove_student(self._student)

databaseconnection.py:
 

import pymysql
class DatabaseConnection:
    _instance = None
    _connection=None
    def __new__(cls,*args,**kwargs):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
        return cls._instance
    def connect(self,host,user,password,database,port=3306,charset='utf8mb4'):
        if self._connection is None or not self._connection.open:
            try:
                self._connection=pymysql.connect(
                    host=host,
                    user=user,
                    password=password,
                    database=database,
                    port=port,
                    charset=charset,
                )
                if self._connection.open:
                    print("成功连接数据库")
            except pymysql.MySQLError as e:
                print(f"无法连接数据库: {e}")
                self._connection = None  # 连接失败时设置为None
        return self._connection

    def get_connection(self):
        # 如果连接已经关闭或从未建立,这里可以添加重新连接的逻辑,假设连接在创建后一直保持打开状态
        return self._connection
    def close_connection(self):
        if self._connection and self._connection.is_connected():
            self._connection.close()
            print("MySQL连接已关闭")
            self._connection = None  # 设置为None以便下次可以重新连接

factory.py:
 

class Student:
    def __init__(self, name, student_id):
        self.name = name
        self.student_id = student_id

    def __str__(self):
        return f"{self.name} ({self.student_id})"


class StudentFactory:
    @staticmethod
    def create_student(name, student_id):
        return Student(name, student_id)

observe.py

# observer.py

class Observer:
    def update(self, message):
        pass


class StudentObserver(Observer):
    def update(self, message):
        print(f"Observer received: {message}")

proxy.py:

class StudentProxy:
    def __init__(self, student=None):
        self._student = student
        self._has_permission = False #权限标志
        self._info_cache = None  # 缓存学生信息
        self._access_log = []  # 访问日志

    def grant_permission(self):
        self._has_permission = False
        self._access_log.append("Permission granted.")

    def revoke_permission(self):
        self._has_permission = False
        self._access_log.append("Permission revoked.")

    def get_student_info(self):
        self._access_log.append("Attempted to get student info.")
        if self._has_permission and self._student:
            return str(self._student)
        return "无法访问"

strategy.py:

class SortingStrategy:
    def sort(self, students):
        pass


class SortByName(SortingStrategy):
    def sort(self, students):
        return sorted(students, key=lambda student: student.name)


class SortByGrade(SortingStrategy):
    def sort(self, students):
        return sorted(students, key=lambda student: student.student_id)  # Assuming student_id is a grade.

项目配置:

补充设计模式的相关内容:

1、工厂方法模式:展示如何定义一个创建对象的接口,让子类决定实例化哪一个类,以增强灵活性。
2、单例模式:实现确保一个类只有一个实例,并提供一个全局访问点的经典模式。

4、代理模式:代理模式的核心在于为某个对象提供一个代理对象,以控制对目标对象的访问
它为其他对象提供了一种代理以控制对这个对象的访问。代理对象在客户端和目标对象之间起到中介的作用,客户端通过代理对象间接地访问目标对象。

当你需要一个访问控制层来检查客户端对目标对象的访问权限时。
当你希望隐藏目标对象的实现细节或复杂性时。
当你需要在访问目标对象之前执行一些额外的操作(如日志记录、安全检查等)时。
当你需要延迟加载目标对象,直到真正需要它时才创建时。
在你的StudentProxy类中,代理模式主要用于控制对student对象的访问权限。通过修改grant_permission方法,你可以正确地授予或拒绝访问权限。


3、命令模式:操作的执行者(如StudentManager)与请求者完全分离。通过命令对象,可以方便地实现撤销操作、操作日志记录等功能。
5、策略模式:允许在运行时改变对象的行为,展示了算法与上下文之间的解耦。动态选择不同的排序算法对学生列表进行排序
6、观察者模式:模拟一种一对多的关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并被自动更新。


门面模式:提供了一种方式来简化复杂系统的接口,使外部调用更加便捷。


1、创建型:创建对象,将对象的创建与使用分离,主要有工厂方法、单例模式
           抽象化创建过程:创建型模式将创建对象的过程进行了抽象和封装,客户程序只需使用对象,而不必关心对象的创建逻辑。
           单一实例控制:如单例模式,确保某个类只有一个实例,并提供全局访问点。
2、结构型:解决对象之间组合关系、接口定义和实现等结构性问题,通过组合对象或类以形成更强大的结构。
           包括外观模式、适配器模式、代理模式、装饰模式、桥接模式、组合模式、享元模式
      组合关系:关注对象或类之间的组合和关联关系,通过组合或聚合来构建更大的结构。
      接口转换:如适配器模式,将一个类的接口转换成客户希望的另一个接口,使原本接口不兼容的类可以一起工作。
      封装性:通过封装内部实现细节,提供简化的接口,降低系统的复杂性。
3、行为型:描述程序在运行时复杂的流程控制,即描述多个类或对象之间如何相互协作以完成单个对象都无法单独完成的任务
            包括策略模式、模板方法模式、观察者模式、命令模式、迭代器模式、中介者模式、备忘录模式、状态模式、责任链模式、访问者模式
    算法与职责分配:算法和对象间职责的分配,描述对象和类的行为以及它们之间的通信模式。
    灵活性:通过封装算法或行为,使得系统在不同条件下可以灵活地选择不同的算法或行为。
    对象间协作:强调对象之间的协作,通过组合或聚合来实现复杂的控制流和交互。

标签:课程设计,name,Python,self,---,tk,student,._,def
From: https://blog.csdn.net/weixin_65589140/article/details/144944257

相关文章

  • 多模态论文笔记——U-ViT(国内版DiT)
    大家好,这里是好评笔记,公主号:Goodnote,专栏文章私信限时Free。本文详细介绍U-ViT的模型架构和实验细节,虽然没有后续的DiT在AIGC领域火爆,但为后来的研究奠定了基础,但其开创性的探索值得学习。文章目录论文背景架构训练细节1.长跳跃连接(LongSkipConnections)2.时......
  • Java基于springboot+vue的宠物领养寄养救助系统pythgon+nodejs+php-计算机毕业设计
    目录功能和技术介绍具体实现截图开发核心技术:开发环境开发步骤编译运行核心代码部分展示系统设计详细视频演示可行性论证软件测试源码获取功能和技术介绍该系统基于浏览器的方式进行访问,采用springboot集成快速开发框架,前端使用vue方式,基于es5的语法,开发工具Intelli......
  • 【操作系统---Linux】一文带你入门了解线程和虚拟地址空间中页表映射的秘密(内附手绘底
    绪论​每日激励:“努力去做自己该做的,但是不要期待回报,不是付出了就会有回报的,做了就不要后悔,不做才后悔。—Jack”绪论​:本章是LInux中非常重要的线程部分,通过了解线程的基本概念:线程到底是什么、进程和线程的关系、线程为什么叫轻量级进程、为什么要用线程(他的比较......
  • 你内部啥样跟我没关系 - 迭代器模式(Iterator Pattern)
    迭代器模式(IteratorPattern)迭代器模式(IteratorPattern)迭代器模式概述迭代器模式结构图迭代器模式涉及的角色talkischeap,showyoumycode总结迭代器模式(IteratorPattern)迭代器模式(IteratorPattern)是一种行为型设计模式,它提供了一种方法顺序访问一个聚合对象......
  • 第15章 汇编语言--- 数组与指针
    汇编语言是一种低级编程语言,它几乎与特定的计算机架构一一对应。在汇编语言中,数组和指针的概念不像在高级语言(如C或C++)中那样直接存在,但可以通过对内存地址的操作来实现类似的功能。在汇编语言中,数组可以被看作是一系列连续存储的相同类型的元素,而指针则是用来存放某个变量......
  • 日常训练2025-1-5
    日常训练2025-1-5L.BridgeRenovationrating:1400https://codeforces.com/problemset/problem/2038/L思路(贪心)需要思考每种板子的组合方式,最好的组合方式是两个2号板子和1个1号板子,加起来只消耗一块板子。其次是三块1号板子加起来只消耗一块板子。然后就是两块任意板子......
  • 【MyBatis-Plus ORM】数据库和实体类映射
    在开发中,数据库和Java对象的映射(ORM)是一个绕不开的话题,而MyBatis-Plus(MP)作为一款优秀的ORM工具,帮我们简化了繁琐的数据库操作。本文将从数据库基础、表与实体映射、复杂对象映射、自定义SQL等角度,深入探讨MP的数据库映射功能。一、数据库设计基本知识在开始O......
  • (赠源码)基于python+Django+msyql协同过滤的音乐推荐系统的设计与实现74526-计算机原创
    摘要随着音乐产业的数字化和个性化需求不断增长,音乐推荐系统作为提升用户体验和促进音乐产业发展的重要工具备受关注。本研究旨在基于协同过滤算法,结合Python编程语言和Django框架,构建一款高效的音乐推荐系统。通过分析用户的历史播放记录、喜好和行为数据,系统能够实现个性......
  • java+SpringBoot+msyql教师招聘管理系统81097-计算机毕设原创(赠源码)
    目 录摘要1绪论1.1研究背景1.2研究意义1.3论文结构与章节安排2系统分析2.1可行性分析2.1.1技术可行性2.1.2经济可行性2.1.3操作可行性2.2系统流程分析2.2.1数据增加流程2.2.2数据修改流程2.2.3数据删除流程2.3系统功能分析2.3.......
  • (免费领源码)基于Java#SpringBoot#mysql#微信小程序的健身打卡平台的设计与实现13606-计
    摘 要随着人们健康意识的不断提高,健身已经成为一种流行的生活方式。然而,传统的健身方式往往受到时间和空间的限制,无法满足人们随时随地进行健身打卡的需求。为了解决这个问题,提出了一种基于SpringBoot微信小程序的健身打卡平台的设计与实现。本平台旨在提供一个便捷、实......