图书管理系统

本系统是一个简单图书管理系统,主要目的是使用它来管理图书,比如管理员负责图书日常管理工作,如各种基本信息的录入、修改、删除、查询操作。本系统的主要功能有图书信息的查询、录入、修改、删除及图书统计以及读者借还书功能等。

刚开始老师就说最好不要选择这种比较老套的项目,网上已经有很多人做过的。但我不同意老师的观点,我觉得即使是这种很普通没有新意的项目,想要做好做细致还是很难的。刚开始的时候确实很有干劲努力地去学wxpython,想用CS模式做一个客户端出来。最后因为学习界面而忽视了数据库的部分,导致大部分时间花在了界面上(关键是花了很多时间界面也没做好,失败啊),做为一个作品已经跑题了。一个人的项目,没办法。


数据库设计

  • 系统E-R图:

174757_QEcG_590878.jpg


  • 数据库表的设计:

书籍信息表

图书IDIDVARCHAR2(15)
图书名称 NAMEVARCHAR2(30)
图书作者 AUTHORVARCHAR2(30)
出版社PUBLISHERVARCHAR2(30)
类别 TYPE VARCHAR2(30)
价格 PRICENUMBER
是否借阅BORROWEDVARCHAR2(2)

用户表

用户编号 USERID VARCHAR2(15)
用户姓名USERNAMEVARCHAR2(30)
密码USERPWDVARCHAR2(20)
权限PERMISSIONVARCHAR2(10)

读者表

读者编号READERIDVARCHAR2(15)
读者姓名READERNAMEVARCHAR2(30)
性别 GENDER VARCHAR2(2)
借书数目 BBN NUMBER

借书表

图书编号BOOKIDVARCHAR2(15)
读者编号 READERIDVARCHAR2(15)
借书日期 BORROWDATEVARCHAR2(20)

还书表

图书编号BOOKIDVARCHAR2(15)
读者编号READERIDVARCHAR2(15)
还书日期RETURNDATEVARCHAR2(20)

界面设计

最后贴几张运行的界面(做完这个我再也不想做界面了,以前觉得会做界面多酷啊::>_<:: )

181507_xryt_590878.jpg

181524_PvmO_590878.jpg

181539_GBft_590878.jpg

代码被我弄成一坨了,本来是写出多个文件的,后来干脆直接弄一起,DEBUG还方便些。可能还是分模块多个文件逻辑更清晰吧。

#! /usr/bin/env python
# -*- coding: gbk -*-
''' A simple library management system.'''
#--------------------------------------------------------------------------------
import wx
import cx_Oracle
import wx.html
import wx.grid
import string
import cx_Oracle
import sys
#--------------------------------------------------------------------------------
#defining my database class

class LMSDatabase:

    def __init__(self, username, userpwd, host, port, dbname):
        self.username = username
        self.userpwd  = userpwd
        self.host     = host
        self.port     = port
        self.dbname   = dbname
        self.dsn      = cx_Oracle.makedsn(self.host, self.port, self.dbname)
        self.connection= cx_Oracle.connect(self.username, self.userpwd, self.dsn)

    def execute(self, sql):
        ''' (LMSDatabase, str) -> Type
            Execute a sql statement, if there is a result, return the result,
            else return None.
        '''
        cursor = self.connection.cursor()
        cursor.execute(sql)
        if sql.startswith('select') or sql.startswith('SELECT'):
            result = cursor.fetchall()
            if result:
                return result
            else:
                return None

    def OnClose(self):
        self.connection.close()

#-------------------------------------------------------------------------------
#defining BookTable class for displaying table in the main frame
        
class BookEntry:

    def __init__(self, data, dataTypes, colLabels):
        self.data =      data
        self.dataTypes = dataTypes
        self.colLabels = colLabels

class BookTable(wx.grid.PyGridTableBase):

    def __init__(self, entries):
        wx.grid.PyGridTableBase.__init__(self)
        self.entries = entries

    def GetNumberRows(self):
        return len(self.entries.data) + 1

    def GetNumberCols(self):
        return len(self.entries.data[0])

    def GetColLabelValue(self, col):
        return self.entries.colLabels[col]

    def IsEmptyCell(self, row, col):
        return False

    def GetValue(self, row, col):
        try:
            return self.entries.data[row][col]
        except IndexError:
            return ''

    def SetValue(self, row, col, value):
        pass

class BookGrid(wx.grid.Grid):
    def __init__(self, parent, database):
        wx.grid.Grid.__init__(self, parent, id = -1)
    
        self.dataTypes = [wx.grid.GRID_VALUE_STRING,
                     wx.grid.GRID_VALUE_STRING,
                     wx.grid.GRID_VALUE_STRING,
                     wx.grid.GRID_VALUE_STRING,
                     wx.grid.GRID_VALUE_FLOAT,
                     wx.grid.GRID_VALUE_STRING
                     ]
        self.colLabels = ['图书编号', '名称', '作者', '出版社', '价格', '分类', '是否借阅']

        result = database.execute('SELECT * FROM BOOK ORDER BY BOOKID ASC')
        bookData = []
        for eachTuple in result:
            bookData.append(list(eachTuple))
        bookEntry = BookEntry(bookData, self.dataTypes, self.colLabels)
        tableBase = BookTable(bookEntry)
            
        self.SetTable(tableBase, True)
        self.SetRowLabelSize(0)
        self.AutoSizeColumns(False)
        self.AutoSizeRows(True)

#-------------------------------------------------------------------------------
#defining the LoginDialog class
            
class LoginDialog(wx.Dialog):
    def __init__(self, parent, id, title,  
                       size = (350, 200),
                       pos = wx.DefaultPosition,
                       style = wx.DEFAULT_DIALOG_STYLE, useMetal = False):
        try:
            self.lmsDatabase = LMSDatabase('scott', 'tiger', 'localhost', 1521, 'system')
        except cx_Oracle.DatabaseError, exc:
            error, = exc.args
            wx.MessageBox('Oracle-Error-Message: ' + error.message, 'Error')
            raise SystemExit
            
        pre = wx.PreDialog()
        pre.Create(parent, id, title, pos, size, style)
        self.PostCreate(pre)
        self.user, self.password = '', ''
        self.CreateSizer()
        
    def dataEntries(self):
        return (('用户  ', 0, self.OnUser),('密码  ', wx.TE_PASSWORD, self.OnPassword))
                                    
    def dataButtons(self):
        return ((wx.ID_OK, '确定'),(wx.ID_CANCEL, '取消'))
        
    def CreateSizer(self):
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(wx.StaticText(self, -1, '请输入用户名和密码'), 0, wx.ALIGN_CENTER | wx.ALL, 5)
        
        for eachLabel, eachStyle, eachHandler in self.dataEntries():
            self.CreateEntry(sizer, eachLabel, eachStyle, eachHandler)
            
        sizer.Add(wx.StaticLine(self, -1, size=(20, -1), style=wx.LI_HORIZONTAL),
                            0, wx.GROW | wx.ALIGN_CENTER_VERTICAL | wx.RIGHT | wx.TOP, 5)
        btnsizer = wx.StdDialogButtonSizer()
        for eachId, eachLabel in self.dataButtons():
            self.CreateButton(btnsizer, eachId, eachLabel)
        btnsizer.Realize()
        sizer.Add(btnsizer, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5)
        self.SetSizer(sizer)
        sizer.Fit(self)
            
    def CreateEntry(self, sizer, label, style, handler):
        box = wx.BoxSizer(wx.HORIZONTAL)
        box.Add(wx.StaticText(self, -1, label), 0, wx.ALIGN_CENTER | wx.ALL, 5)
        text = wx.TextCtrl(self, -1, "", size = (80, -1), style = style)
        text.Bind(wx.EVT_TEXT, handler)
        box.Add(text, 1, wx.ALIGN_CENTER | wx.ALL, 5)
        sizer.Add(box, 0, wx.GROW | wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5)
        
    def CreateButton(self, btnsizer, id, label):
        button = wx.Button(self, id, label)
        if id == wx.ID_OK:
            button.SetDefault()
        btnsizer.AddButton(button)        
        
    def OnUser(self, event):
        self.user = event.GetString()
        
    def OnPassword(self, event):
        self.password = event.GetString()

    def Authentication(self):
        '''
        Return true if it is successfully authenticated.
        '''
        sql = 'select * from users where username = \'' + self.user + '\''
        try:
            result = self.lmsDatabase.execute(sql)
        except cx_Oracle.DatabaseError, exc:
            error, = exc.args
            wx.MessageBox('Oracle-Error-Message: ' + error.message, 'Error') 

        if result and self.password == result[0][2]:
            return result
        else:
            return False
       
#------------------------------------------------------------------------------- 
#Main frame class
            
class LibraryManFrame(wx.Frame):
    def __init__(self, parent = None):
        self.title = "图书馆管理系统"
        wx.Frame.__init__(self, parent, -1, self.title, size = (800, 600),
                          style = wx.DEFAULT_FRAME_STYLE ^ (wx.RESIZE_BORDER | wx.MAXIMIZE_BOX))

        #database connection
        try:
            self.lmsDatabase = LMSDatabase('scott', 'tiger', 'localhost', 1521, 'system')
        except cx_Oracle.DatabaseError, exc:
            error, = exc.args
            wx.MessageBox('Oracle-Error-Message: ' + error.message, 'Error')
            raise SystemExit
        
        #permision setting
        self.userID = ''
        self.permission = 'Visitor'
            
        #main ui
        self.panel = wx.Panel(self, -1)
        self.panel.SetBackgroundColour("White")
        self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)

        text = wx.StaticText(self.panel, -1, self.title)
        font = wx.Font(18, wx.ROMAN, wx.NORMAL, wx.NORMAL)
        text.SetFont(font)
        
        self.search = wx.SearchCtrl(self.panel, value = "请输入您要搜索的图书名或关键字", size = (400, -1), style = wx.TE_PROCESS_ENTER)

        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.sizer.Add(text, 0, wx.ALL | wx.CENTER, 40)
        self.sizer.Add(self.search, 0, wx.ALL | wx.CENTER, 15)

        #Functions for initialize the App
        self.createMenuBar()

        #Bindings
        self.Bind(wx.EVT_TEXT_ENTER, self.OnDoSearch, self.search)
        self.panel.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)
        self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)

        self.SetSizer(self.sizer)
        
    def menuData(self):
        return [("&菜单", (
                    ("&登录系统", "Login", self.OnLogin),
                    ("&保存修改", "Save Change", self.OnSave),
                    ("", "", ""),
                    ("&退出系统", "Quit", self.OnCloseWindow))),
                ("&图书馆", (
                    ("&图书归还", "Book Statistic", self.OnReturn),
                    ("&图书借阅", "Book Statistic", self.OnBorrow),
                    ("&图书统计", "Book Statistic", self.OnStatistics),
                    ("&打印报表", 'Print Report Forms', self.OnReportForms),
                    ("&管理图书", (
                        ("&添加图书", "Add book information", self.OnAdd),
                        ("&修改图书", "Modify book information", self.OnModify),
                        ("&删除图书", "Delete book information", self.OnDelete))),
                    ("&关于程序", "Software information", self.OnAbout)))
                ]

    def createMenuBar(self):
        menuBar = wx.MenuBar()

        for eachMenuData in self.menuData():
            menuLabel = eachMenuData[0]
            menuItems = eachMenuData[1]
            menuBar.Append(self.createMenu(menuItems), menuLabel)

        self.SetMenuBar(menuBar)

    def createSubMenu(self, menuData):
        menu = wx.Menu()
        for eachLabel, eachStatus, eachHandler in menuData:
            if not eachLabel:
                menu.AppendSeparator()
                continue
            menuItem = menu.Append(-1, eachLabel, eachStatus)
            self.Bind(wx.EVT_MENU, eachHandler, menuItem)
        return menu
    
    def createMenu(self, menuData):
        menu = wx.Menu()
        for eachItem in menuData:
            if len(eachItem) == 2:
                label = eachItem[0]
                subMenu = self.createSubMenu(eachItem[1])
                menu.AppendMenu(wx.NewId(), label, subMenu)
            else:
                self.createMenuItem(menu, *eachItem)
        return menu

    def createMenuItem(self, menu, label, status, handler, kind = wx.ITEM_NORMAL):
        if not label:
            menu.AppendSeparator()
            return
        menuItem = menu.Append(-1, label, status, kind)
        self.Bind(wx.EVT_MENU, handler, menuItem)
        
#-------------------------------------------------------------------------------
#---------------------handlers are here-----------------------------------------
        
    def OnLogin(self, evt):
        dialog = LoginDialog(None, -1, "登录")
        result = dialog.ShowModal()
        if result == wx.ID_OK:
            if dialog.Authentication():
                login_info = dialog.Authentication()
                self.permission = login_info[0][-1]
                self.userID = login_info[0][0]
                if self.permission == 'Admin':
                    wx.MessageBox('以管理员身份登陆成功!', 'Bonjour!')
                else:
                    wx.MessageBox('登陆成功!', 'Bonjour!')
            else:
                wx.MessageBox('用户名或密码错误', 'Error!')
        dialog.Destroy()

    def OnBorrow(self, evt):
        if self.permission == 'Visitor':
            wx.MessageBox('您现在的身份为游客,\n请以用户身份登录!', '提示')
        if self.permission == 'Admin':
            wx.MessageBox('您无法使用此功能。', '提示')
        if self.permission == 'User':
            dlg = BorrowDialog(self, '请输入您要借阅的图书编号和日期:', '借书')
            result = dlg.ShowModal()
            if result == wx.ID_OK:
                id, borrowtime = dlg.GetValue()[0], dlg.GetValue()[1]
                sql = 'SELECT * FROM BOOK WHERE BOOKID = \'' + id + '\''
                try:
                    result = self.lmsDatabase.execute(sql)
                    borrow_sql = 'SELECT BORROWED FROM BOOK WHERE BOOKID = \'%s\'' % id
                    borrow_status = self.lmsDatabase.execute(borrow_sql)[0][0]
                except cx_Oracle.DatabaseError, exc:
                    error, = exc.args
                    wx.MessageBox('Oracle-Error-Message: ' + error.message, 'Error')
                if result and borrow_status == 'N':
                    #update owner table
                    sql_owner = 'INSERT INTO OWNER VALUES(\'%s\', \'%s\', \'%s\')' % (id, self.userID, borrowtime)
                    self.lmsDatabase.execute(sql_owner)
                    #update reader table
                    num_result = self.lmsDatabase.execute('SELECT BBN FROM READER WHERE READERID = \'%s\'' % self.userID)
                    num = num_result[0][0]
                    sql_reader = 'UPDATE READER SET BBN = %s WHERE READERID = \'%s\'' %(str(num + 1), self.userID)
                    self.lmsDatabase.execute(sql_reader)
                    #upadate book table
                    sql_book = 'UPDATE BOOK SET BORROWED = \'Y\' WHERE BOOKID = \'%s\'' % id
                    self.lmsDatabase.execute(sql_book)
                else:
                    wx.MessageBox('您要借阅的图书不存在或已被借阅!', '提示')
            dlg.Destroy()

    def OnReturn(self,evt):
        if self.permission == 'Visitor':
            wx.MessageBox('您现在的身份为游客,\n请以用户身份登录!', '提示')
        if self.permission == 'Admin':
            wx.MessageBox('您无法使用此功能。', '提示')
        if self.permission == 'User':
            dlg = BorrowDialog(self, '请输入您要归还的图书编号和日期:', '还书')
            result = dlg.ShowModal()
            if result == wx.ID_OK:
                id, returntime = dlg.GetValue()[0], dlg.GetValue()[1]
                sql = 'SELECT * FROM BOOK WHERE BOOKID = \'' + id + '\''
                try:
                    result = self.lmsDatabase.execute(sql)
                    borrow_sql = 'SELECT BORROWED FROM BOOK WHERE BOOKID = \'%s\'' % id
                    borrow_status = self.lmsDatabase.execute(borrow_sql)[0][0]
                except cx_Oracle.DatabaseError, exc:
                    error, = exc.args
                    wx.MessageBox('Oracle-Error-Message: ' + error.message, 'Error')
                if result and borrow_status == 'Y':
                    #update returnbook table
                    sql_owner = 'INSERT INTO returnbook VALUES(\'%s\', \'%s\', \'%s\')' % (id, self.userID, returntime)
                    self.lmsDatabase.execute(sql_owner)
                    #update reader table
                    num_result = self.lmsDatabase.execute('SELECT BBN FROM READER WHERE READERID = \'%s\'' % self.userID)
                    num = num_result[0][0]
                    sql_reader = 'UPDATE READER SET BBN = %s WHERE READERID = \'%s\'' %(str(num - 1), self.userID)
                    self.lmsDatabase.execute(sql_reader)
                    #upadate book table
                    sql_book = 'UPDATE BOOK SET BORROWED = \'N\' WHERE BOOKID = \'%s\'' % id
                    self.lmsDatabase.execute(sql_book)
                else:
                    wx.MessageBox('您要归还的图书不存在或已归还!', '提示')
    
    def OnStatistics(self, evt):
        raw_types = self.lmsDatabase.execute('select type from BOOK')
        bookTypes = []
        for types in raw_types:
            for eachType in types[0].split('\\'):
                if eachType not in bookTypes:
                    bookTypes.append(eachType)
         
        bookStatistic = {}
        for eachType in bookTypes:
            sql = 'select * from Book where Type like \'%' + eachType + '%\''
            num = len(self.lmsDatabase.execute(sql))
            bookStatistic[eachType] = num

        dlg = StatisticDialog(self, bookStatistic)
        dlg.ShowModal()
        dlg.Destroy()

    def OnReportForms(self, evt):
        result = self.lmsDatabase.execute('SELECT * FROM BOOK')
        if result:
            dlg = ReportFormsDialog(self)
            dlg.ShowModal()
            dlg.Destroy()
        else:
            wx.MessageBox('表为空!', '信息')
        
    def OnSave(self, evt):
        self.lmsDatabase.connection.commit()

    def OnAdd(self, evt):
        if self.permission == 'Admin':
            dlg = BookDialog(self, '请输入需要添加的图书信息')
            result = dlg.ShowModal()
            if result == wx.ID_OK:
                sql = 'insert into Book (BOOKID, BOOKNAME, AUTHOR, PUBLISHER, PRICE, TYPE, BORROWED) VALUES ' + dlg.GetString()
                try:
                    self.lmsDatabase.execute(sql)
                except cx_Oracle.DatabaseError, exc:
                    error, = exc.args
                    wx.MessageBox('Oracle-Error-Message: ' + error.message, 'Error')
            dlg.Destroy()
        else:
            wx.MessageBox('权限不够!\n请以管理员身份登录!', '提示')

    def OnModify(self, evt):
        if self.permission == 'Admin':
            dlg = BookDialog(self, '请输入需要修改的图书信息')
            result = dlg.ShowModal()
            if result == wx.ID_OK:
                newBookData = dlg.GetValue()
                sql = 'UPDATE BOOK SET BOOKNAME = \'' + newBookData[1] + '\', AUTHOR = \'' + \
                       newBookData[2] + '\', PUBLISHER = \'' + newBookData[3] + '\', PRICE = ' + \
                       newBookData[4] + ', TYPE = \'' + newBookData[5] + '\' WHERE BOOKID = \'' + \
                       newBookData[0] + '\''
                   
                try:
                    self.lmsDatabase.execute(sql)
                except cx_Oracle.DatabaseError, exc:
                    error, = exc.args
                    wx.MessageBox('Oracle-Error-Message: ' + error.message, 'Error')
            dlg.Destroy()
        else:
            wx.MessageBox('权限不够!\n请以管理员身份登录!', '提示')

    def OnDelete(self, evt):
        if self.permission == 'Admin':
            dlg = DelDialog(self, '请输入需要删除的图书ID')
            result = dlg.ShowModal()
            if result == wx.ID_OK:
                sql = 'DELETE FROM BOOK WHERE BookID = \'%s\'' % dlg.GetValue()
                try:
                    self.lmsDatabase.execute(sql)
                except cx_Oracle.DatabaseError, exc:
                    error, = exc.args
                    wx.MessageBox('Oracle-Error-Message: ' + error.message, 'Error')
            dlg.Destroy()
        else:
            wx.MessageBox('权限不够!\n请以管理员身份登录!', '提示')

    def OnDoSearch(self, evt):
        #To destroy the text used for the last search
        pChildren = self.panel.GetChildren()
        sChildren = self.sizer.GetChildren()
        sWidgets = []
        for sChild in sChildren:
            sWidgets.append(sChild.GetWindow())

        for pChild in pChildren:
            if pChild not in sWidgets:
                pChild.Destroy()
        #-----------------------------------------------
            
        keywords = self.search.GetValue()
        if keywords:
            sql = 'SELECT * FROM BOOK WHERE BOOKNAME LIKE \'%' + keywords + '%\' ORDER BY BOOKID ASC'
            result = self.lmsDatabase.execute(sql)
            if result:
                resultText = '找到的相关图书信息如下:\n'
                for eachTuple in result:
                    for eachElem in eachTuple:
                        resultText = resultText + str(eachElem) + ' '

                    resultText += '\n'
            else:
                resultText = '未找到相关图书信息。\n'
            text = wx.StaticText(self.panel, -1, resultText)
            self.sizer.Insert(2, text, flag = wx.ALL | wx.CENTER)
            self.sizer.Layout()
            self.sizer.Detach(text)
            
    def OnEraseBackground(self, evt):
        """
        Add a picture to the background
        """
        dc = evt.GetDC()
        # Added by me
        cliWidth, cliHeight = self.GetClientSize()

        if not dc:
            dc = wx.ClientDC(self)
            rect = self.GetUpdateRegion().GetBox()
            dc.SetClippingRect(rect)
        dc.Clear()

        try:
            image_file = 'background.png'
            bmp = wx.Bitmap(image_file)
            dc.DrawBitmap(bmp, 0, 0)
        except wx._core.PyAssertionError:
            wx.MessageBox("Image file %s not found" % image_file, 'Error')
            raise SystemExit        
        
    def OnCloseWindow(self, event):
        if wx.OK == wx.MessageBox('是否保存您所做的修改?', '提示', wx.OK | wx.CANCEL):
            self.OnSave(self)
        self.lmsDatabase.OnClose()
        self.Destroy()

    def OnAbout(self, evt):
        dlg = LibraryManAbout(self)
        dlg.ShowModal()
        dlg.Destroy()

class LibraryManAbout(wx.Dialog):
    text = '''
<html>
<body bgcolor="#9DC678">
<center><table bgcolor="#455481" width="100%" cellspacing="0"
cellpadding="0" border="1">
<tr>
    <td align="center"><h1>Library Management System!</h1></td>
</tr>
</table>
</center>
<p><b>Librabry Management System</b> really took me a lot of time
to finish it. But I love the process!
</p>

<p><b>wxPython</b> are brought to you by
<b>Robin Dunn</b> and <b>Total Control Software</b>, Copyright
&copy; 1997-2006.</p>
</body>
</html>
'''

    def __init__(self, parent):
        wx.Dialog.__init__(self, parent, -1, 'About',
                          size=(440, 400) )

        html = wx.html.HtmlWindow(self)
        html.SetPage(self.text)
        button = wx.Button(self, wx.ID_OK, "Okay")

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(html, 1, wx.EXPAND|wx.ALL, 5)
        sizer.Add(button, 0, wx.ALIGN_CENTER|wx.ALL, 5)

        self.SetSizer(sizer)
        self.Layout()

class BorrowDialog(wx.Dialog):
    def __init__(self, parent, aboutText, capital):
        wx.Dialog.__init__(self, parent, -1, capital)
        self.aboutText = aboutText
        self.textCtrl = []
        self.CreateSizer()

    def CreateSizer(self):
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(wx.StaticText(self, -1, self.aboutText), 0, wx.ALL, 5)
        sizer.Add(wx.StaticLine(self), 0, wx.EXPAND|wx.ALL, 5)

        sizer_n = wx.BoxSizer(wx.HORIZONTAL)
        sizer_n.Add(wx.StaticText(self, -1, '图书编号: '), 0, wx.ALIGN_RIGHT)
        id = wx.TextCtrl(self)
        self.textCtrl.append(id)
        sizer_n.Add(id, 0, wx.ALL)

        sizer_t = wx.BoxSizer(wx.HORIZONTAL)
        sizer_t.Add(wx.StaticText(self, -1, '借阅时间: '), 0, wx.ALIGN_RIGHT)
        time = wx.TextCtrl(self)
        self.textCtrl.append(time)
        sizer_t.Add(time, 0, wx.ALL)

        sizer.Add(sizer_n, 0, wx.EXPAND|wx.ALL, 5)
        sizer.Add(sizer_t, 0, wx.EXPAND|wx.ALL, 5)
        self.CreateButton(sizer)
        self.SetSizer(sizer)
        sizer.Fit(self)

    def CreateButton(self, sizer):
        # Use standard button IDs
        okay   = wx.Button(self, wx.ID_OK)
        okay.SetDefault()
        cancel = wx.Button(self, wx.ID_CANCEL)

        btns = wx.StdDialogButtonSizer()
        btns.AddButton(okay)
        btns.AddButton(cancel)
        btns.Realize()
        sizer.Add(btns, 0, wx.EXPAND|wx.ALL, 5)

    def GetValue(self):
        return (self.textCtrl[0].GetValue(), self.textCtrl[1].GetValue())

class ReportFormsDialog(wx.Dialog):
    def __init__(self, parent):
        wx.Dialog.__init__(self, parent, -1, '报表打印')
        grid = BookGrid(self, parent.lmsDatabase)
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(grid, 0, wx.ALL, 10)
        self.SetSizer(sizer)
        sizer.Fit(self)       

class StatisticTable(wx.grid.PyGridTableBase):
            
    def __init__(self, data, rowLabels=None, colLabels=None):
        wx.grid.PyGridTableBase.__init__(self)
        self.data = data
        self.rowLabels = rowLabels
        self.colLabels = colLabels
        
    def GetNumberRows(self):
        return len(self.rowLabels)

    def GetNumberCols(self):
        return len(self.colLabels)

    def GetColLabelValue(self, col):
        if self.colLabels:
            return self.colLabels[col]
        
    def GetRowLabelValue(self, row):
        if self.rowLabels:
            return self.rowLabels[row]
        
    def IsEmptyCell(self, row, col):
        return False

    def GetValue(self, row, col):
        return self.data[row][col + 1]

    def SetValue(self, row, col, value):
        pass  

class StatisticGrid(wx.grid.Grid):
    def __init__(self, parent, data, rowLabels, colLabels):
        wx.grid.Grid.__init__(self, parent, -1)
        tableBase = StatisticTable(data, rowLabels, colLabels)
        self.SetTable(tableBase)

class StatisticDialog(wx.Dialog):
    def __init__(self, parent, bookStatistic):
        wx.Dialog.__init__(self, parent, -1, '图书统计')
        data = []
        for key in bookStatistic:
            data.append((key, bookStatistic[key]))
              
        rowLabels = bookStatistic.keys()
        colLabels = ['图书数量']
        grid = StatisticGrid(self, data, rowLabels, colLabels)
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(grid, 0, wx.ALL, 10)
        self.SetSizer(sizer)
        sizer.Fit(self)
        

class BookInfoValidator(wx.PyValidator):
    def __init__(self, flag):
         wx.PyValidator.__init__(self)
         self.flag = flag
         self.Bind(wx.EVT_CHAR, self.OnChar)

    def Clone(self):
         """
         Note that every validator must implement the Clone() method.
         """
         return BookInfoValidator(self.flag)

    def Validate(self, win):
         textCtrl = self.GetWindow()
         text = textCtrl.GetValue()

         if len(text) == 0:
             wx.MessageBox("This field must contain some text!", "Error")
             textCtrl.SetBackgroundColour("pink")
             textCtrl.SetFocus()
             textCtrl.Refresh()
             return False
         else:
             textCtrl.SetBackgroundColour(
                 wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW))
             textCtrl.Refresh()
             return True

    def TransferToWindow(self):
         return True 

    def TransferFromWindow(self):
         return True

    def OnChar(self, evt):
        key = evt.GetKeyCode()
        if key <= 255:
            char = chr(key)
            if self.flag == "no-alpha" and char in string.letters:
                return
            if self.flag == "no-digit" and char in string.digits:
                return
        if self.flag != "any" and key > 255:
            return            
        evt.Skip()

class BookDialog(wx.Dialog):
    def __init__(self, parent, aboutText):
        wx.Dialog.__init__(self, parent, -1, "图书信息")
        self.about   = wx.StaticText(self, -1, aboutText)
        self.bookEntry = []
        self.CreateSizer()
        
    def dataText(self):
        return (('图书编号:', 'no-alpha'), ('图书名称:', 'any'),
                ('作者:', 'any'), ('出版社:', 'any'),
                ('价格:', 'any'), ('类别:', 'any')
                )

    def CreateSizer(self):
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.about, 0, wx.ALL, 5)
        sizer.Add(wx.StaticLine(self), 0, wx.EXPAND|wx.ALL, 5)

        fgs = wx.FlexGridSizer(6, 2, 5, 5)
        for eachLabel, eachFlag in self.dataText():
            self.CreateEntry(fgs, eachLabel, eachFlag)

        sizer.Add(fgs, 0, wx.EXPAND|wx.ALL, 5)
        self.CreateButton(sizer)
        self.SetSizer(sizer)
        sizer.Fit(self)

    def CreateEntry(self, sizer, label, flag):
        sizer.Add(wx.StaticText(self, -1, label), 0, wx.ALIGN_RIGHT)
        text = wx.TextCtrl(self, validator=BookInfoValidator(flag))
        self.bookEntry.append(text)
        sizer.Add(text, 0, wx.EXPAND)

    def CreateButton(self, sizer):
        # Use standard button IDs
        okay   = wx.Button(self, wx.ID_OK)
        okay.SetDefault()
        cancel = wx.Button(self, wx.ID_CANCEL)

        btns = wx.StdDialogButtonSizer()
        btns.AddButton(okay)
        btns.AddButton(cancel)
        btns.Realize()
        sizer.Add(btns, 0, wx.EXPAND|wx.ALL, 5)
        
    def GetValue(self):
        result = []
        for eachText in self.bookEntry:
            result.append(eachText.GetValue())
        return result

    def GetString(self):
        '''
        Return a string in the format like this  ('', '', '').
        '''
        raw_result = self.GetValue()
        result = '(' + '\'' + raw_result[0] + '\', ' + '\'' + raw_result[1] + '\', ' + \
                 '\'' + raw_result[2] + '\', ' + '\'' + raw_result[3] + '\', ' + \
                 raw_result[4] + ', ' + '\'' + raw_result[-1] + '\', \'N\')'

        return result        

class DelDialog(wx.Dialog):
    def __init__(self, parent, aboutText):
        wx.Dialog.__init__(self, parent, -1, "删除")
        self.about   = wx.StaticText(self, -1, aboutText)
        self.text = []
        self.CreateSizer()

    def CreateSizer(self):
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.about, 0, wx.ALL, 5)
        sizer.Add(wx.StaticLine(self), 0, wx.EXPAND|wx.ALL, 5)

        sizer_t = wx.BoxSizer(wx.HORIZONTAL)
        sizer_t.Add(wx.StaticText(self, -1, '图书ID: '), 0, wx.ALIGN_RIGHT)
        text = wx.TextCtrl(self)
        self.text.append(text)
        sizer_t.Add(text, 0, wx.ALL)

        sizer.Add(sizer_t, 0, wx.EXPAND|wx.ALL, 5)
        self.CreateButton(sizer)
        self.SetSizer(sizer)
        sizer.Fit(self)

    def CreateButton(self, sizer):
        # Use standard button IDs
        okay   = wx.Button(self, wx.ID_OK)
        okay.SetDefault()
        cancel = wx.Button(self, wx.ID_CANCEL)

        btns = wx.StdDialogButtonSizer()
        btns.AddButton(okay)
        btns.AddButton(cancel)
        btns.Realize()
        sizer.Add(btns, 0, wx.EXPAND|wx.ALL, 5)

    def GetValue(self):
        return self.text[0].GetValue()

class LibraryManApp(wx.App):
    
    def OnInit(self):
        frame = LibraryManFrame(None)
        frame.Show(True)
        self.SetTopWindow(frame)
        return True
   
if __name__ == '__main__':
    app = LibraryManApp(False)
    app.MainLoop()


转载于:https://my.oschina.net/seandor/blog/138937

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值