Python Tkinter学生信息管理系统(支持增删改查)

在本教程中,我们将实现一个有吸引力且用户友好的桌面应用程序学生管理系统。此应用程序用于存储学生的数据。我们可以将此应用程序用作我们学院的一个小项目。这个应用程序基本上是使用 python 框架 Tkinter 实现的,它提供了实现桌面应用程序的工具。

主要创建了 2 个框架,一个框架存储数据,另一个框架用于显示数据。

数据形式

存储每个学生的一些信息,如学号、姓名、父亲姓名、学历、专业、联系电话和地址。
4个功能来添加数据更新数据删除数据清除数据。并且所有字段都是必需的,如果数据存在于数据库中则删除数据,如果数据从数据库中获取并且在数据库中可用则更新数据。
还可以快速选中一条数据然后修改进行新增

显示所有数据

在这里插入图片描述

添加数据

在这里插入图片描述

删除数据

在这里插入图片描述

修改数据

在这里插入图片描述

查询数据

在这里插入图片描述

源码及使用方法:

创建表code

# SQ.py
import sqlite3
from sqlite3 import Error


def create_connection(db_file):
    """ create a database connection to the SQLite database
        specified by db_file
    :param db_file: database file
    :return: Connection object or None
    """
    conn = None
    try:
        conn = sqlite3.connect(db_file)
        return conn
    except Error as e:
        print(e)

    return conn


def create_table(conn, create_table_sql):
    """ create a table from the create_table_sql statement
    :param conn: Connection object
    :param create_table_sql: a CREATE TABLE statement
    :return:
    """
    try:
        c = conn.cursor()
        c.execute(create_table_sql)
    except Error as e:
        print(e)


def main():
    database = r"SQLite_Python.db"

    sql_create_projects_table = """CREATE TABLE IF NOT EXISTS students (
                                      Roll_no varchar(15) PRIMARY KEY,
                                      Name varchar(30) NOT NULL,
                                      Father_Name varchar(55) NOT NULL,
                                      Gender varchar(10) NOT NULL,
                                      Category varchar(10) NOT NULL,
                                      Branch varchar(30) NOT NULL,
                                      Year varchar(10) NOT NULL,
                                      Contact_no varchar(10) NOT NULL,
                                      Address varchar(200) NOT NULL
                                    );"""

    # create a database connection
    conn = create_connection(database)

    # create tables
    if conn is not None:
        # create projects table
        create_table(conn, sql_create_projects_table)

    else:
        print("Error! cannot create the database connection.")


if __name__ == '__main__':
    main()

主程序code

# Student.py
from tkinter import *
from tkinter import ttk
from tkinter import messagebox
import sqlite3

# from icecream import ic


class Student:
    width = 1550
    height = 800
    def __init__(self, root):
        self.root = root
        self.root.title("学生信息管理系统")
        screen_width = root.winfo_screenwidth()
        screen_height = root.winfo_screenheight()

        x = int(screen_width / 2 - Student.width / 2)
        y = int(screen_height / 2 - Student.height / 2)

        self.root.geometry(f"{Student.width}x{Student.height}+{x}+{y}")
        self.root.resizable(False, False)
        self.roll_no = StringVar()
        self.name = StringVar()
        self.father_name = StringVar()
        self.gen = StringVar()
        self.category = StringVar()
        self.branch = StringVar()
        self.year = StringVar()
        self.contact = StringVar()
        self.search_by = StringVar()
        self.search_txt = StringVar()
        self.totalrecord = StringVar()

        headinglbl = Label(root, text="Student Management System", font=("arial", 24, "bold"), bg='#7F7FFF', fg='red')
        headinglbl.pack(side=TOP, fill=X)

        # ***********Frame-1***************
        entry_frame = Frame(root, bd=5, relief='ridge', bg='#E0E0EE')
        entry_frame.place(x=20, y=50, width=350, height=745)

        # Labels of frame-1
        reg_lbl = Label(entry_frame, text="注册表单", font=("arial", 20, "bold"), bg='#E0E0EE', fg='red')
        reg_lbl.grid(row=0, columnspan=2)

        roll_lbl = Label(entry_frame, text="学号", font=("Heiti TC", 13), bg='#E0E0EE')
        roll_lbl.grid(row=1, column=0, sticky='w', padx=10, pady=11)

        name_lbl = Label(entry_frame, text="姓名", font=("Heiti TC", 13), bg='#E0E0EE')
        name_lbl.grid(row=2, column=0, sticky='w', padx=10, pady=11)

        Fname_lbl = Label(entry_frame, text="父亲名字", font=("Heiti TC", 13), bg='#E0E0EE')
        Fname_lbl.grid(row=3, column=0, sticky='w', padx=10, pady=11)

        gen_lbl = Label(entry_frame, text="姓别", font=("Heiti TC", 13), bg='#E0E0EE')
        gen_lbl.grid(row=4, column=0, sticky='w', padx=10, pady=11)

        cat_lbl = Label(entry_frame, text="学历", font=("Heiti TC", 13), bg='#E0E0EE')
        cat_lbl.grid(row=5, column=0, sticky='w', padx=10, pady=11)

        branch_lbl = Label(entry_frame, text="专业", font=("Heiti TC", 13), bg='#E0E0EE')
        branch_lbl.grid(row=6, column=0, sticky='w', padx=10, pady=11)

        yr_lbl = Label(entry_frame, text="学年制", font=("Heiti TC", 13), bg='#E0E0EE')
        yr_lbl.grid(row=7, column=0, sticky='w', padx=10, pady=11)

        phn_lbl = Label(entry_frame, text="联系方式", font=("Heiti TC", 13), bg='#E0E0EE')
        phn_lbl.grid(row=8, column=0, sticky='w', padx=10, pady=11)

        add_lbl = Label(entry_frame, text="家庭地址", font=("Heiti TC", 15), bg='#E0E0EE')
        add_lbl.grid(row=9, column=0, sticky='w', padx=10, pady=11)

        # Entry box of Frame-1
        roll_entry = Entry(entry_frame, width=29, bd=3, bg='#E0E0EE', relief='ridge', font=("STSong", 12), textvariable=self.roll_no)
        roll_entry.grid(row=1, column=1, sticky='w', padx=10, pady=11)

        name_entry = Entry(entry_frame, width=29, bd=3, bg='#E0E0EE', relief='ridge', font=("STSong", 12), textvariable=self.name)
        name_entry.grid(row=2, column=1, sticky='w', padx=10, pady=11)

        fname_entry = Entry(entry_frame, width=29, bd=3, bg='#E0E0EE', relief='ridge', font=("STSong", 12), textvariable=self.father_name)
        fname_entry.grid(row=3, column=1, sticky='w', padx=10, pady=11)

        gen_combo = ttk.Combobox(entry_frame, state='readonly', width=18, textvariable=self.gen)
        gen_combo['values'] = ('男', '女')
        gen_combo.current(0)
        gen_combo.grid(row=4, column=1, sticky='w', padx=10, pady=11)

        cat_combo = ttk.Combobox(entry_frame, state='readonly', width=18, textvariable=self.category)
        cat_combo['values'] = ('本科', '大专', '中专', '高中')
        cat_combo.current(0)
        cat_combo.grid(row=5, column=1, sticky='w', padx=10, pady=11)

        branch_combo = ttk.Combobox(entry_frame, state='readonly', width=18, textvariable=self.branch)
        branch_combo['values'] = ('哲学','经济学','法学','教育学','文学','历史学','理学','工学','农学','医学','管理学','艺术学')
        branch_combo.current(0)
        branch_combo.grid(row=6, column=1, sticky='w', padx=10, pady=11)

        yr_combo = ttk.Combobox(entry_frame, state='readonly', width=18, textvariable=self.year)
        yr_combo['values'] = ('4年', '3年', '2年', '1年')
        yr_combo.current(0)
        yr_combo.grid(row=7, column=1, sticky='w', padx=10, pady=11)

        phn_entry = Entry(entry_frame, width=29, bd=3, bg='#E0E0EE', relief='ridge', font=("STSong", 12), textvariable=self.contact)
        phn_entry.grid(row=8, column=1, sticky='w', padx=10, pady=11)

        self.add_txt = Text(entry_frame, width=29, height=5, font=("Times", 12))
        self.add_txt.grid(row=9, column=1, sticky='w', padx=10, pady=11)

        # ***************Functions*********************

        def add_data():
            con = sqlite3.connect('SQLite_Python.db')
            cur = con.cursor()
            # ic(str(self.roll_no.get()))
            cur.execute("select * from students where Roll_no=?", (str(self.roll_no.get()), ))
            rows = cur.fetchall()
            if len(rows) != 0:
                messagebox.showerror('Error', f'学号:{str(self.roll_no.get())} 的学生信息已存在!')
            else:
                if self.roll_no.get() == "" or self.name.get() == "" or self.father_name.get() == "" or self.contact.get() == "" or self.add_txt.get(
                        '1.0', END) == "" or len(self.contact.get()) != 11:
                    messagebox.showerror('Error', '所有字段都不能为空且联系方式必须长度11位')
                else:
                    info = str(self.roll_no.get())
                    cur.execute("""insert into students values(?,?,?,?,?,?,?,?,?)""", (
                    self.roll_no.get(), self.name.get(), self.father_name.get(), self.gen.get(), self.category.get(),
                    self.branch.get(), self.year.get(), self.contact.get(), self.add_txt.get('1.0', END)))
                    con.commit()
                    con.close()
                    fetch_data()
                    clear_data()
                    messagebox.showinfo('Success', f'{info} 添加成功!')

        def fetch_data():
            con = sqlite3.connect('SQLite_Python.db')
            cur = con.cursor()
            cur.execute('select * from students')
            rows = cur.fetchall()

            if rows != 0:
                self.totalrecord.set(len(rows))
                table.delete(*table.get_children())

                for row in rows:
                    table.insert('', END, values=row)
                con.commit()
            con.close()

        def clear_data():
            self.roll_no.set("")
            self.name.set("")
            self.father_name.set("")
            self.gen.set("")
            self.category.set("")
            self.branch.set("")
            self.year.set("")
            self.contact.set("")

            self.add_txt.delete('1.0', END)

        def focus(e):
            cursor = table.focus()
            content = table.item(cursor)
            row = content['values']
            self.roll_no.set(row[0])
            self.name.set(row[1])
            self.father_name.set(row[2])
            self.gen.set(row[3])
            self.category.set(row[4])
            self.branch.set(row[5])
            self.year.set(row[6])
            self.contact.set(row[7])
            self.add_txt.delete('1.0', END)
            self.add_txt.insert(END, row[8])

        def update_data():

            if self.roll_no.get() == "" or self.name.get() == "" or self.father_name.get() == "" or self.contact.get() == "" or self.add_txt.get(
                    '1.0', END) == "" or len(self.contact.get()) != 11:
                messagebox.showerror('Error', '必须填写所有字段')
            else:
                info = self.roll_no.get()
                con = sqlite3.connect('SQLite_Python.db')
                cur = con.cursor()
                cur.execute(
                    'update students set Name=? , Father_Name=? , Gender=? , Category=? , Branch=? , Year=? , Contact_no=? , Address=? where Roll_no=? ',
                    (self.name.get(), self.father_name.get(), self.gen.get(), self.category.get(), self.branch.get(),
                     self.year.get(), self.contact.get(), self.add_txt.get('1.0', END), self.roll_no.get()))
                con.commit()
                con.close()
                fetch_data()
                clear_data()
                messagebox.showinfo('Success', f'{info} 更新成功')

        def delete_data():
            if self.roll_no.get():
                info = self.roll_no.get()
                con = sqlite3.connect('SQLite_Python.db')
                cur = con.cursor()
                cur.execute('delete from students where Roll_no=?', (info,))
                con.commit()
                con.close()
                fetch_data()
                clear_data()
                messagebox.showinfo('Success', f'{info}已被删除成功')
            else:
                messagebox.showinfo('Warning', f'未选中任何数据')


        def search():
            con = sqlite3.connect('SQLite_Python.db')
            cur = con.cursor()
            if str(self.search_by.get()) == "学号":
                search = 'Roll_no'
            else:
                search = 'Contact_no'
            cur.execute("select * from students where " + search + " LIKE '%" + str(
                self.search_txt.get()) + "%'")
            rows = cur.fetchall()

            if len(rows) != 0:
                table.delete(*table.get_children())

                for row in rows:
                    table.insert('', END, values=row)

                con.commit()
            else:
                messagebox.showinfo('Not found', 'Record not found')

            con.close()

        # **********Frame-3 Button**************

        btn_frame = Frame(entry_frame, bd=5, relief='ridge', bg='#E0E0EE')
        btn_frame.place(x=15, y=590, width=310, height=120)

        add_btn = Button(btn_frame, text='Add', font=("", 12), command=add_data, width="7", bg='#E0E0EE')
        add_btn.grid(row=0, column=1, padx=50, pady=10)

        update_btn = Button(btn_frame, text='Update', font=("", 12), command=update_data, width="7", bg='#E0E0EE')
        update_btn.grid(row=0, column=2, padx=10, pady=10)

        delete_btn = Button(btn_frame, text='Delete', font=("", 12), command=delete_data, width="7", bg='#E0E0EE')
        delete_btn.grid(row=1, column=1, padx=50, pady=10)

        clear_btn = Button(btn_frame, text='Clear', font=("", 12), command=clear_data, width="7", bg='#E0E0EE')
        clear_btn.grid(row=1, column=2, padx=10, pady=10)

        # ***********Frame-2***************
        data_frame = Frame(root, bd=5, relief='ridge', bg='#E0E0EE')
        data_frame.place(x=380, y=50, width=1145, height=745)

        # ***********Frame-2 code*****************
        search_lbl = Label(data_frame, text="Search by", font=("", 13), bg='#E0E0EE')
        search_lbl.grid(row=0, column=0, sticky='w', padx=10, pady=14)

        search_combo = ttk.Combobox(data_frame, state='readonly', textvariable=self.search_by)
        search_combo['values'] = ('学号', '联系方式')
        search_combo.current(0)
        search_combo.grid(row=0, column=1, sticky='w', padx=10, pady=14)

        search_entry = Entry(data_frame, bd=3, relief='ridge', font=("", 12), width=15, textvariable=self.search_txt)
        search_entry.grid(row=0, column=2, sticky='w', padx=10, pady=14)

        show_btn = Button(data_frame, text='查找', font=("", 12), command=search)
        show_btn.grid(row=0, column=3, padx=10, pady=10)

        showall_btn = Button(data_frame, text='查找所有', font=("", 12), command=fetch_data)
        showall_btn.grid(row=0, column=4, padx=10, pady=10)

        total_lbl = Label(data_frame, text="Total Records", font=("", 13), bg='#E0E0EE')
        total_lbl.grid(row=1, column=0, sticky='w', padx=10, pady=8)

        totalrecord_lbl = Label(data_frame, text="Total Records", font=("", 13), textvariable=self.totalrecord)
        totalrecord_lbl.grid(row=1, column=1, sticky='w', padx=10, pady=8)

        # ************Frame-3 Treeview***************

        view_frame = Frame(data_frame, bd=5, relief='ridge', bg='wheat')
        view_frame.place(x=20, y=100, width=1080, height=620)

        x_scroll = Scrollbar(view_frame, orient=HORIZONTAL)
        y_scroll = Scrollbar(view_frame, orient=VERTICAL)
        table=ttk.Treeview(view_frame,columns=('Roll_no.','Name','Father_Name','Gender','Category','Branch','Year','Contact_no.','Address'),xscrollcommand=x_scroll.set,yscrollcommand=y_scroll.set)
        x_scroll.pack(side=BOTTOM, fill=X)
        y_scroll.pack(side=RIGHT, fill=Y)
        x_scroll.configure(command=table.xview)
        y_scroll.configure(command=table.yview)

        table.heading("Roll_no.", text="学号")
        table.heading("Name", text="姓名")
        table.heading("Father_Name", text="父亲名字")
        table.heading("Gender", text="姓别")
        table.heading("Category", text="学历")
        table.heading("Branch", text="专业")
        table.heading("Year", text="学年制")
        table.heading("Contact_no.", text="联系方式")
        table.heading("Address", text="家庭住址")

        table.column("Roll_no.", width=100)
        table.column("Name", width=100)
        table.column("Father_Name", width=100)
        table.column("Gender", width=100)
        table.column("Category", width=100)
        table.column("Branch", width=100)
        table.column("Year", width=100)
        table.column("Contact_no.", width=100)
        table.column("Address", width=100)
        table['show'] = 'headings'
        table.bind('<ButtonRelease-1>', focus)
        fetch_data()
        table.pack(fill=BOTH, expand=1)


root = Tk()
ob = Student(root)
root.mainloop()




  1. SQ.pyStudent.py 放置同一文件夹下
  2. 先执行SQ.py创建数据表。
  3. 再执行Student.py即可
  • 10
    点赞
  • 90
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ko-walski

太难了,求鼓励

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值