Python实现带GUI和连接数据库的图书管理系统

文章目录

  • 前言
  • 二、建立数据库library
    • 2.1 book表
    • 2.2 borrow表
    • 2.3 user表
  • 三、各个模块介绍
    • 3.1 初始界面initial
    • 3.2 manager登录注册模块
    • 3.3 ID模块
    • 3.4 reader登录注册模块
    • 3.5 m_operation管理员操作界面
    • 3.6 r_operation读者操作模块
    • 3.7 search模块(动态查询)
  • 四、总结


前言

大三上学期的程序设计实训大作业,挑了其中一个我认为最简单的的《图书管理系统》来写。用python写是因为py有自带的GUI,即tkinter模块,对初次接触GUI的新手会比较友好。编译器我用的是Pycharm,你需要检查你的编译器是否带了tkinter模块和pymysql模块,没有的话需要下载安装,具体方法可以百度,很简单。界面很丑,凑合看哦!如果你没有了解过tkinter,建议先去知乎,csdn上面搜索自学一下入门教程,这样就比较容易理解我的东西啦!
** 特别注意:数据库表是我后来根据记忆建的,可能跟代码中的SQL语句的顺序有出入,实际数据库的字段值属性值顺序按照代码里的为准,修改一下数据库就好啦!代码是没问题的o( ̄︶ ̄)o **
Python实现带GUI和连接数据库的图书管理系统_第1张图片

二、建立数据库library

** 特别注意:这个表是我后来根据记忆建的,可能跟代码中的SQL语句的顺序有出入,实际数据库的字段值属性值顺序按照代码里的为准,修改一下数据库就好啦!代码是没问题的o( ̄︶ ̄)o **
Python实现带GUI和连接数据库的图书管理系统_第2张图片
如图所示,软件是Navicat,给library建表。

2.1 book表

存储图书的相关信息,包括书名,作者,类型,数量。主码是name和author。
Python实现带GUI和连接数据库的图书管理系统_第3张图片

2.2 borrow表

借书单,存储借书人ID,书名,作者,借书时间。主码是name和author。
Python实现带GUI和连接数据库的图书管理系统_第4张图片

2.3 user表

使用者,包括ID,password,job是个只有1位的数字,0表示读者,1表示管理员,登录的时候通过检测其job然后选择是跳转到读者界面还是管理员界面。
Python实现带GUI和连接数据库的图书管理系统_第5张图片

三、各个模块介绍

Python实现带GUI和连接数据库的图书管理系统_第6张图片

3.1 初始界面initial

import tkinter as tk
import reader
import manager

def frame():#初始界面
    global root
    root=tk.Tk()
    root.geometry('900x700')
    root.title('西电图书管理系统')
    lable0=tk.Label(root,text='欢迎来到XDU图书馆',bg='pink',font=('微软雅黑',50)).pack()#上
	#canvas是个画布,想要插入图片的话首先要定义个canvas
    canvas=tk.Canvas(root,height=500,width=500)#中
    image_file=tk.PhotoImage(file='2.gif')
    #图片文件的后缀必须是.gif,且亲测不能自行鼠标右键重命名更改成.gif,要用win10里内置的画图功能,打开图片然后另存为的时候选择.gif
    #图片文件必须放到你的项目目录里边才有效
    image=canvas.create_image(250,100,image=image_file)
    canvas.place(x=170,y=170)

    lable1=tk.Label(root,text='请选择用户类型:',font=('微软雅黑',20)).place(x=80,y=500)#下
    tk.Button(root, text='读  者',font=('微软雅黑',15),width=10, height=2,command=exit_reader).place(x=350, y=420)
    tk.Button(root, text='管理员',font=('微软雅黑',15),width=10, height=2,command=exit_manager).place(x=350, y=550)

    root.mainloop()#必须要有这句话,你的页面才会动态刷新循环,否则页面不会显示 

def exit_reader():#跳转至读者界面
    root.destroy()
    reader.frame()

def exit_manager():#跳转至管理员界面
    root.destroy()
    manager.frame()

if __name__ == '__main__':
    frame()

Python实现带GUI和连接数据库的图书管理系统_第7张图片
效果就是上面这样的。
这个初始界面就比较简单,点击读者跳转到读者界面,点击管理员跳转到管理员界面。

3.2 manager登录注册模块

当我们从初始界面选择“管理员”,那么这时候调用exit_manager()函数,来到了管理员界面

import tkinter as tk
import tkinter.messagebox as msg #这个是会弹出一个警告/提示小框
import initial
import pymysql
import ID

def frame():#管理员界面
    global root
    root= tk.Tk()
    root.geometry('900x700')
    root.title('西电图书管理系统')
    lable0 = tk.Label(root, text='管理员登录', bg='pink', font=('微软雅黑', 50)).pack()  # 上

    canvas = tk.Canvas(root, height=500, width=500)  # 中
    image_file = tk.PhotoImage(file='2.gif')
    image = canvas.create_image(250, 100, image=image_file)
    canvas.place(x=190, y=170)

    lable1 = tk.Label(root, text='请选择:', font=('微软雅黑', 20)).place(x=80, y=400)  # 下
    tk.Button(root, text='登录', font=('微软雅黑', 15), width=10, height=2, command=login).place(x=150, y=500)
    tk.Button(root, text='注册', font=('微软雅黑', 15), width=10, height=2, command=register).place(x=350, y=500)
    tk.Button(root, text='退出', font=('微软雅黑', 15), width=10, height=2, command=exit_manager).place(x=550, y=500)
    root.mainloop()

def login():#登录小窗口
    global root1
    root1=tk.Tk()
    root1.wm_attributes('-topmost', 1)#将登录窗口置顶不至于被遮到下面
    root1.title('管理员登录')
    root1.geometry('500x300')

    lable1 = tk.Label(root1, text='账号:', font=25).place(x=100,y=50)
    lable2 = tk.Label(root1, text='密码:', font=25).place(x=100, y=100)

    global entry_name, entry_key
    name=tk.StringVar()
    key = tk.StringVar()

    entry_name = tk.Entry(root1, textvariable=name, font=25)
    entry_name.place(x=180, y=50)
    entry_key = tk.Entry(root1, textvariable=key, font=25,show='*')
    entry_key.place(x=180,y=100)
    # 百度:tkinter要求由按钮(或者其它的插件)触发的控制器函数不能含有参数,若要给函数传递参数,需要在函数前添加lambda:
    button1 = tk.Button(root1, text='确定', height=2, width=10, command=lambda: ID.id_check('1'))
    button1.place(x=210, y=180)
#当我们输入账号和密码,点击确定时候,会调用ID模块里的id_check()函数,1是参数,表示其身份是管理员
def register():#注册小窗口
    global root2
    root2 = tk.Tk()
    root2.wm_attributes('-topmost', 1)
    root2.title('管理员注册')
    root2.geometry('500x300')

    lable1 = tk.Label(root2, text='账号:', font=25).place(x=100, y=50)
    lable2 = tk.Label(root2, text='密码:', font=25).place(x=100, y=100)
    lable2 = tk.Label(root2, text='确认密码:', font=25).place(x=80, y=150)

    global entry_name, entry_key, entry_confirm
    name = tk.StringVar()
    key = tk.StringVar()
    confirm = tk.StringVar()
    entry_name = tk.Entry(root2, textvariable=name, font=25)
    entry_name.place(x=180, y=50)
    entry_key = tk.Entry(root2, textvariable=key, font=25, show='*')
    entry_key.place(x=180, y=100)
    entry_confirm = tk.Entry(root2, textvariable=confirm,font=25, show='*')
    entry_confirm.place(x=180, y=150)
    # 百度:tkinter要求由按钮(或者其它的插件)触发的控制器函数不能含有参数,若要给函数传递参数,需要在函数前添加lambda:
    button1 = tk.Button(root2, text='确定', height=2, width=10, command=lambda: ID.id_write('1'))
    button1.place(x=210, y=200)
#当我们点击确定的时候,会调用ID模块里的id_write()函数,1是参数,表示其身份是管理员
def exit_manager():#退出管理员界面,跳转至初始界面
    root.destroy()
    initial.frame()

Python实现带GUI和连接数据库的图书管理系统_第8张图片
Python实现带GUI和连接数据库的图书管理系统_第9张图片

3.3 ID模块

ID模块相当于后端了,主要实现连接数据库,检查账号的有无,核对密码,注册等功能。

import tkinter as tk
import tkinter.messagebox as msg
import pymysql
import initial
import manager
import reader
import m_operation
import r_operation
def id_check(a):#检查账号
    global id
    if a == '1':#在管理员界面下登录,参数是1
    #把账号/密码框框里输入的字符串赋值给id/password
        id = manager.entry_name.get()
        password = manager.entry_key.get()
    else:#在读者界面下登录,参数是0
        id = reader.entry_name.get()
        password = reader.entry_key.get()
    getid()#最后得到id
    #连接数据库,root是你数据库的用户名,应该是默认的是root,qwer是你数据库的密码,library是你要连接的数据库名字
    db = pymysql.connect("localhost", "root", "qwer", "library")
    #建立游标cursor,这个游标可以类比指针,这样理解比较直观
    cursor = db.cursor()
    sql = "SELECT password FROM user WHERE id='%s' AND job='%s'" % (id,a)
    cursor.execute(sql) #sql语句被执行
    result = cursor.fetchone()#得到的结果返回给result数组
    if result:#如果查询到了账号存在
            if password == result[0]:#result[0]是数组中的第一个结果
                success_login(a)#密码对上了,进入对应的读者/管理员操作界面
            else:#有账号但密码没对上
               msg._show(title='错误!',message='账号或密码输入错误!')
    else:#没有账号
        msg._show(title='错误!',message='您输入的用户不存在!请先注册!')
        if a=='1':
            manager.root1.destroy()#关闭登录小窗口,回到管理员界面
        elif a=='0':
            reader.root1.destroy()
    db.close()#查询完一定要关闭数据库啊

def success_login(a):#成功登录
    if a == '1':
        manager.root1.destroy()
        m_operation.frame()#销毁登录注册界面,跳转到管理员的操作界面

    elif a == '0':
        reader.root1.destroy()
        r_operation.frame()#销毁登录注册界面,跳转到读者的操作界面

def id_write(a):#写入(注册)账号
    db = pymysql.connect("localhost", "root", "qwer", "library")
    cursor = db.cursor()
    if a=='1':#跟check函数里边十分类似
        id = manager.entry_name.get()#得到输入的账号
        password = manager.entry_key.get()#得到输入的密码
        confirm = manager.entry_confirm.get()#得到输入的确认密码
    elif a=='0':
        id = reader.entry_name.get()
        password = reader.entry_key.get()
        confirm = reader.entry_confirm.get()

    sql0 = "SELECT id FROM user WHERE id='%s' AND job='%s'" % (id,a)
    sql1 = "INSERT INTO user VALUES(%s,%s,%s) " % (id, password, a)
#首先检查两次输入的密码是否一致,一致后再检查注册的账号是否已经存在
    if password == confirm:
        cursor.execute(sql0)
        result = cursor.fetchone()
        if result:
            msg.showerror(title='错误!', message='该账号已被注册,请重新输入!')
        else:
            cursor.execute(sql1)
            db.commit()
            db.close()
            msg.showinfo(title='成功!', message='注册成功,请登录!')

    else:
        msg.showerror(title='错误!', message='两次密码不一致,请重新输入!')

def getid():
    return id

3.4 reader登录注册模块

同2.2,如法炮(pao二声)制。
(咳咳学好语文也好重要呀!)

import tkinter as tk
import initial
import ID
def frame():
    global root
    root= tk.Tk()
    root.geometry('900x700')
    root.title('西电图书管理系统')
    lable0 = tk.Label(root, text='读者登录', bg='pink', font=('微软雅黑', 50)).pack()  # 上

    canvas = tk.Canvas(root, height=500, width=500)  # 中
    image_file = tk.PhotoImage(file='2.gif')
    image = canvas.create_image(250, 100, image=image_file)
    canvas.place(x=190, y=170)

    lable1 = tk.Label(root, text='请选择:', font=('微软雅黑', 20)).place(x=80, y=400)  # 下
    tk.Button(root, text='登录', font=('微软雅黑', 15), width=10, height=2, command=login).place(x=150, y=500)
    tk.Button(root, text='注册', font=('微软雅黑', 15), width=10, height=2, command=register).place(x=350, y=500)
    tk.Button(root, text='退出', font=('微软雅黑', 15), width=10, height=2, command=exit_reader).place(x=550, y=500)
    root.mainloop()

def login():
    global root1
    root1=tk.Tk()
    root1.wm_attributes('-topmost', 1)
    root1.title('读者登录')
    root1.geometry('500x300')

    lable1 = tk.Label(root1, text='账号:', font=25).place(x=100, y=50)
    lable2 = tk.Label(root1, text='密码:', font=25).place(x=100, y=100)

    global entry_name, entry_key
    name=tk.StringVar()
    key = tk.StringVar()

    entry_name=tk.Entry(root1,textvariable=name,font=25)
    entry_name.place(x=180,y=50)
    entry_key=tk.Entry(root1, textvariable=key, font=25,show='*')
    entry_key.place(x=180,y=100)
    # 百度:tkinter要求由按钮(或者其它的插件)触发的控制器函数不能含有参数,若要给函数传递参数,需要在函数前添加lambda
    button1=tk.Button(root1,text='确定',height=2,width=10,command=lambda :ID.id_check('0'))
    button1.place(x=210,y=180)

def register():
    global root2
    root2 = tk.Tk()
    root2.wm_attributes('-topmost', 1)
    root2.title('读者注册')
    root2.geometry('500x300')

    lable1 = tk.Label(root2, text='账号:', font=25).place(x=100, y=50)
    lable2 = tk.Label(root2, text='密码:', font=25).place(x=100, y=100)
    lable2 = tk.Label(root2, text='确认密码:', font=25).place(x=80, y=150)

    global entry_name, entry_key, entry_confirm
    name = tk.StringVar()
    key = tk.StringVar()
    confirm = tk.StringVar()
    entry_name = tk.Entry(root2, textvariable=name, font=25)
    entry_name.place(x=180, y=50)
    entry_key = tk.Entry(root2, textvariable=key, font=25, show='*')
    entry_key.place(x=180, y=100)
    entry_confirm = tk.Entry(root2, textvariable=confirm,font=25, show='*')
    entry_confirm.place(x=180, y=150)
    # 百度:tkinter要求由按钮(或者其它的插件)触发的控制器函数不能含有参数,若要给函数传递参数,需要在函数前添加lambda
    button1 = tk.Button(root2, text='确定', height=2, width=10, command=lambda: ID.id_write('0'))
    button1.place(x=210, y=200)

def exit_reader():#退出管理员界面,跳转至初始界面
    root.destroy()
    initial.frame()

3.5 m_operation管理员操作界面

当我们终于成功注册/登录之后,来到了管理员的操作界面。
Python实现带GUI和连接数据库的图书管理系统_第10张图片

import tkinter as tk
import tkinter.messagebox as msg
import search
from tkinter import ttk
import pymysql
def frame():
    window=tk.Tk()
    window.title('管理员')
    window.geometry('900x700')
    lable0 = tk.Label(window, text='欢迎来到XDU图书馆', bg='pink', font=('微软雅黑', 50)).pack()  # 上

    lable1 = tk.Label(window, text='请选择操作:', font=('微软雅黑', 20)).place(x=80, y=400)  # 下
    tk.Button(window, text='进购图书', font=('微软雅黑', 15), width=10, height=2,command=purchase).place(x=350, y=250)
    tk.Button(window, text='注销图书', font=('微软雅黑', 15), width=10, height=2,command=cancel).place(x=350, y=350)
    tk.Button(window, text='信息查询', font=('微软雅黑', 15), width=10, height=2,command=search.frame).place(x=350, y=450)
    window.mainloop()

def purchase():#进购图书
    global win
    win = tk.Tk()
    win.title('管理员')
    win.geometry('900x300')
    win.wm_attributes('-topmost', 1)
    lable1 = tk.Label(win, text='请填写进购图书的信息:', font=('微软雅黑', 20)).place(x=30, y=100)

    tk.Label(win, text='图书类目:', font=('宋体', 12)).place(x=30, y=200)
    global list#这个是一个下拉页表项,只能从下面的list['values']里边选
    comvalue = tk.StringVar()
    list = ttk.Combobox(win, textvariable=comvalue, height=10, width=10)
    list.place(x=100, y=200)
    list['values'] = ('全部', '人文', '艺术', '计算机', '科技', '杂志')
    list.current(0)#默认显示'全部'

    global b_name
    tk.Label(win, text='书名:', font=('宋体', 12)).place(x=200, y=200)
    b_name = tk.Entry(win, font=('宋体', 12), width=10)
    b_name.place(x=250, y=200)

    global author
    tk.Label(win, text='作者:', font=('宋体', 12)).place(x=350, y=200)
    author = tk.Entry(win, font=('宋体', 12), width=10)
    author.place(x=400, y=200)

    global price
    tk.Label(win, text='价格:', font=('宋体', 12)).place(x=460, y=200)
    price = tk.Entry(win, font=('宋体', 12), width=10)
    price.place(x=510, y=200)

    global amount
    tk.Label(win, text='数量:', font=('宋体', 12)).place(x=560, y=200)
    amount = tk.Entry(win, font=('宋体', 12), width=5)
    amount.place(x=610, y=200)

    tk.Button(win, text='确认添加', font=('宋体', 12), width=10, command=add).place(x=700, y=195)
    
def add():#添加图书信息到数据库中
    sql="INSERT INTO book VALUES('%s','%s','%s','%s','%s')"% (list.get(),b_name.get(),author.get(),price.get(),amount.get())
    db = pymysql.connect("localhost", "root", "qwer", "library")
    cursor = db.cursor()
    cursor.execute(sql)
    db.commit()#这句不可或缺,当我们修改数据完成后必须要确认才能真正作用到数据库里
    db.close()
    msg.showinfo(title='成功!', message='新书已入库!')
def cancel():#撤销图书
    global win
    win = tk.Tk()
    win.title('管理员')
    win.geometry('900x300')
    win.wm_attributes('-topmost', 1)
    lable1 = tk.Label(win, text='请填写注销图书的信息:', font=('微软雅黑', 20)).place(x=30, y=100)

    tk.Label(win, text='图书类目:', font=('宋体', 12)).place(x=30, y=200)
    global list
    comvalue = tk.StringVar()
    list = ttk.Combobox(win, textvariable=comvalue, height=10, width=10)
    list.place(x=100, y=200)
    list['values'] = ('全部', '人文', '艺术', '计算机', '科技', '杂志')
    list.current(0)

    global b_name
    tk.Label(win, text='书名:', font=('宋体', 12)).place(x=200, y=200)
    b_name = tk.Entry(win, font=('宋体', 12), width=10)
    b_name.place(x=250, y=200)

    global author
    tk.Label(win, text='作者:', font=('宋体', 12)).place(x=350, y=200)
    author = tk.Entry(win, font=('宋体', 12), width=10)
    author.place(x=400, y=200)

    tk.Button(win, text='确认注销', font=('宋体', 12), width=10, command=delete).place(x=600, y=195)

def delete():删除图书
    sql = "DELETE FROM book WHERE type='%s' AND name='%s' AND author='%s'" % (list.get(),b_name.get(),author.get())
    db = pymysql.connect("localhost", "root", "qwer", "library")
    cursor = db.cursor()
    cursor.execute(sql)
    db.commit()#这句不可或缺,当我们修改数据完成后必须要确认才能真正作用到数据库里
    msg.showinfo(title='成功!', message='该书已删除!')

Python实现带GUI和连接数据库的图书管理系统_第11张图片

3.6 r_operation读者操作模块

如2.5,如法炮制。但是要引入py内置的datetime模块

import tkinter as tk
import tkinter.messagebox as msg
from tkinter import ttk
import search
import ID
import datetime as dt#datetime
import pymysql

def frame():
    window2=tk.Tk()
    window2.title('读者')
    window2.geometry('700x600')
    lable0 = tk.Label(window2, text='欢迎来到XDU图书馆', bg='pink', font=('微软雅黑', 50)).pack()  # 上

    lable1 = tk.Label(window2, text='请选择操作:', font=('微软雅黑', 20)).place(x=80, y=400)  # 下
    tk.Button(window2, text=' 借  书', font=('微软雅黑', 15), width=10, height=2,command=borrow).place(x=350, y=250)
    tk.Button(window2, text=' 还  书', font=('微软雅黑', 15), width=10, height=2,command=turnback).place(x=350, y=350)
    tk.Button(window2, text='信息查询', font=('微软雅黑', 15), width=10, height=2,command=search.frame).place(x=350, y=450)
    window2.mainloop()

def borrow():
    global win
    win = tk.Tk()
    win.title('读者')
    win.geometry('900x300')
    win.wm_attributes('-topmost', 1)
    lable1 = tk.Label(win, text='请填写所借图书的信息:(书名作者都要填写正确无误!)', bg='pink',font=('微软雅黑', 20)).place(x=30, y=100)

    global b_name
    tk.Label(win, text='书名:', font=('宋体', 12)).place(x=200, y=200)
    b_name = tk.Entry(win, font=('宋体', 12), width=10)
    b_name.place(x=250, y=200)

    global author
    tk.Label(win, text='作者:', font=('宋体', 12)).place(x=350, y=200)
    author = tk.Entry(win, font=('宋体', 12), width=10)
    author.place(x=400, y=200)

    tk.Button(win, text='确认借书', font=('宋体', 12), width=10, command=confirm_borrow).place(x=600, y=195)

def confirm_borrow():
    db = pymysql.connect("localhost", "root", "qwer", "library")
    cursor = db.cursor()
    sql0="SELECT amount FROM book WHERE name='%s' AND author='%s'" % (b_name.get(),author.get())
    cursor.execute(sql0)
    result=cursor.fetchone()
    if result:
        if result != '0':
            time = dt.datetime.now().strftime('%F')#得到的时间不是字符串型,我们要把时间转化成字符串型
            sql = "INSERT INTO borrow VALUES('%s','%s','%s','%s')" % (ID.getid(),b_name.get(),author.get(),time)
            sql1="UPDATE book SET amount=amount-1 WHERE name='%s' AND author='%s'" % (b_name.get(),author.get())
            cursor.execute(sql)
            cursor.execute(sql1)
            db.commit()
            db.close()
            msg.showinfo(title='成功!', message='借书成功!请一个月之内归还')
        else:
            msg.showinfo(title='失败!', message='您借的书库存不足!')
    else:
        msg.showinfo(title='错误!', message='未找到该书!')

def turnback():#还书
    global win
    win = tk.Tk()
    win.title('读者')
    win.geometry('550x600')

    db = pymysql.connect("localhost", "root", "qwer", "library")
    cursor = db.cursor()
    sql0 = "SELECT COUNT(*) FROM borrow WHERE id='%s'" % (ID.getid())
    cursor.execute(sql0)
    result = cursor.fetchone()
    if result[0]==0:
        msg.showinfo(title='错误', message='您还没借过书呢!')
    else :
        lable1 = tk.Label(win, text='查询到您有以下书目未还:', bg='pink', font=('微软雅黑', 20)).place(x=80, y=20)
        tree = ttk.Treeview(win, columns=('1', '2'), show="headings")
        tree.column('1', width=150, anchor='center')
        tree.column('2', width=150, anchor='center')
        tree.heading('1', text='书名')
        tree.heading('2', text='作者')
        tree.place(x=100, y=100)

        sql1 = "SELECT bookname,author FROM borrow WHERE id='%s'" % (ID.getid())
        cursor.execute(sql1)
        result1 = cursor.fetchall()
        for i in range(0,result[0]):
            tree.insert('', i, values=(result1[i]))

        lable2 = tk.Label(win, text='请输入还书信息:', bg='pink', font=('微软雅黑', 20)).place(x=80, y=360)
        lable22=tk.Label(win, text='书名作者都要填写正确无误!', bg='pink', font=('微软雅黑', 20)).place(x=80, y=400)
        global b_name
        tk.Label(win, text='书名:', font=('宋体', 12)).place(x=80, y=480)
        b_name = tk.Entry(win, font=('宋体', 12), width=10)
        b_name.place(x=130, y=480)

        global author
        tk.Label(win, text='作者:', font=('宋体', 12)).place(x=230, y=480)
        author = tk.Entry(win, font=('宋体', 12), width=10)
        author.place(x=280, y=480)

        tk.Button(win, text='确认还书', font=('宋体', 12), width=10, command=confirm_turnback).place(x=395, y=480)
    db.close()

def confirm_turnback():
    db = pymysql.connect("localhost", "root", "qwer", "library")
    cursor = db.cursor()

    sql1 = "UPDATE book SET amount=amount+1 WHERE name='%s' AND author='%s'" % (b_name.get(), author.get())
    cursor.execute(sql1)
    db.commit()

    time1=dt.datetime.now()#获取现在的时间
    sql2="SELECT date FROM borrow WHERE bookname='%s' AND author='%s'"%(b_name.get(),author.get())
    cursor.execute(sql2)
    result = cursor.fetchone()
    day=(time1-result[0]).days#得到时间差,检查图书是否超期
    print(day)
    if day>30:
        msg.showinfo(title='还书成功', message='还书成功,但您已经超期!请下次按时归还')
    else:
        msg.showinfo(title='还书成功', message='还书成功,且未超过30天')

    sql0 = "DELETE FROM borrow WHERE bookname='%s' AND author='%s'"%(b_name.get(), author.get())
    cursor.execute(sql0)
    db.commit()
    db.close()
    win.destroy()

3.7 search模块(动态查询)

由于管理员和读者都有查询图书的功能,故为了减少代码,尽量代码重用,将该功能做成模块。search中要有动态查询,即查询条件的个数是可以改变的。
Python实现带GUI和连接数据库的图书管理系统_第12张图片

import tkinter as tk
import tkinter.messagebox as msg
from tkinter import ttk
import pymysql

def frame():
    global window
    window = tk.Tk()
    window.title('图书查询')
    window.geometry('1200x700')

    tk.Label(window,text='图书类目:',font=('宋体',12)).place(x=220,y=30)

    global list
    comvalue=tk.StringVar()
    list=ttk.Combobox(window,textvariable=comvalue,height=10,width=10)
    list.place(x=300,y=30)
    list['values']=('全部','人文','艺术','计算机','科技','杂志')
    list.current(0)

    global b_name
    tk.Label(window, text='书名:', font=('宋体', 12)).place(x=450, y=30)
    b_name=tk.Entry(window,font=('宋体', 12),width=15)
    b_name.place(x=500,y=30)

    global author
    tk.Label(window, text='作者:', font=('宋体', 12)).place(x=650, y=30)
    author = tk.Entry(window, font=('宋体', 12), width=15)
    author.place(x=700, y=30)

    tk.Button(window,text='搜索',font=('宋体', 12), width=10,command=search).place(x=900,y=25)
    global tree#建立树形图
    yscrollbar = ttk.Scrollbar(window, orient='vertical')#右边的滑动按钮
    tree = ttk.Treeview(window, columns=('1', '2', '3', '4', '5'), show="headings",yscrollcommand=yscrollbar.set)
    tree.column('1', width=150, anchor='center')
    tree.column('2', width=150, anchor='center')
    tree.column('3', width=150, anchor='center')
    tree.column('4', width=150, anchor='center')
    tree.column('5', width=150, anchor='center')
    tree.heading('1', text='类目')
    tree.heading('2', text='书名')
    tree.heading('3', text='作者')
    tree.heading('4', text='价格')
    tree.heading('5', text='库存')
    tree.place(x=200, y=150)
    yscrollbar.place(x=955,y=150)
    window.mainloop()

def search():
#我用了最原始的方法来动态查询
    if list.get()=='全部'and b_name.get()=='' and author.get()=='' :
        sql="SELECT * FROM book "
    elif list.get()=='全部'and b_name.get()=='' and author.get()!='' :
        sql="SELECT * FROM book WHERE author='%s'"%(author.get())
    elif list.get()=='全部'and b_name.get()!='' and author.get()=='' :
        sql = "SELECT * FROM book WHERE name='%s'" % (b_name.get())
    elif list.get() != '全部'  and b_name.get() =='' and author.get() == '' :
        sql = "SELECT * FROM book WHERE type='%s'" % (list.get())
    elif list.get()=='全部'and b_name.get() !='' and author.get()!= '' :
        sql = "SELECT * FROM book WHERE name='%s' AND author='%s'" % (b_name.get(),author.get())
    elif list.get() != '全部' and b_name.get() !='' and author.get() == '' :
        sql = "SELECT * FROM book WHERE type='%s' AND name='%s'" % (list.get(),b_name.get())
    elif list.get() != '全部' and b_name.get() =='' and author.get() != '' :
        sql = "SELECT * FROM book WHERE type='%s' AND author ='%s'" % (list.get(), author.get())
    else :
        sql = "SELECT * FROM book WHERE type='%s' AND name='%s' AND author ='%s'" % (list.get(),b_name.get(), author.get())

    db = pymysql.connect("localhost", "root", "qwer", "library")
    cursor = db.cursor()
    cursor.execute(sql)
    results=cursor.fetchall()
    if results:
        l= len(results)
        for i in range(0,l):#查询到的结果依次插入到表格中
            tree.insert('',i,values=(results[i]))
    else :
        tree.insert('', 0,values=('查询不到结果','查询不到结果','查询不到结果','查询不到结果','查询不到结果'))

    db.close()

四、总结

这是一个较为简单的图书管理系统,其中仍有一些不足。比如人人都能注册管理员账号然后修改图书信息,这会造成系统的不安全。还有就是我们默认的读者借书时候会先查询图书信息,得到图书信息后填写的书名和作者必定是正确的,我没有加上相应的错误处理。然后读者借书超期后有惩罚措施,比如无法借书或限制借书的数量,这个我没有实现,仅仅是提醒了读者有图书已超期。如果有相关问题,欢迎私信作者共同探讨。

提示:转发应得到作者同意,注明出处。

你可能感兴趣的:(数据库,程序设计,tkinter,mysql,python)