所以,我有两段代码。首先是GUI类:
'''
Created on Mar 6, 2013
@author: Zach
'''
# -*- coding: utf-8 -*-
###########################################################################
## Python code generated with wxFormBuilder (version Sep 8 2010)
## http://www.wxformbuilder.org/
##
## PLEASE DO "NOT" EDIT THIS FILE!
###########################################################################
import wx
import wx.grid
from Books import *
###########################################################################
## Class MyFrame1
###########################################################################
class MyFrame1 ( wx.Frame ):
def __init__( self, parent ):
wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = wx.EmptyString, pos = wx.DefaultPosition, size = wx.Size( 734,344 ), style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL )
self.SetSizeHintsSz( wx.DefaultSize, wx.DefaultSize )
bSizer1 = wx.BoxSizer( wx.VERTICAL )
bSizer2 = wx.BoxSizer( wx.HORIZONTAL )
self.patrons_table = wx.grid.Grid( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, 0 )
# Grid
self.patrons_table.CreateGrid( 0, 7 )
self.patrons_table.EnableEditing( True )
self.patrons_table.EnableGridLines( True )
self.patrons_table.SetGridLineColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_APPWORKSPACE ) )
self.patrons_table.EnableDragGridSize( True )
self.patrons_table.SetMargins( 0, 0 )
# Columns
self.patrons_table.SetColSize( 0, 100 )
self.patrons_table.SetColSize( 1, 100 )
self.patrons_table.SetColSize( 2, 100 )
self.patrons_table.SetColSize( 3, 100 )
self.patrons_table.SetColSize( 4, 100 )
self.patrons_table.SetColSize( 5, 100 )
self.patrons_table.SetColSize( 6, 100 )
self.patrons_table.EnableDragColMove( True )
self.patrons_table.EnableDragColSize( True )
self.patrons_table.SetColLabelSize( 40 )
self.patrons_table.SetColLabelValue( 0, "ID" )
self.patrons_table.SetColLabelValue( 1, "Name" )
self.patrons_table.SetColLabelValue( 2, "Address" )
self.patrons_table.SetColLabelValue( 3, "Phone" )
self.patrons_table.SetColLabelValue( 4, "Email" )
self.patrons_table.SetColLabelValue( 5, "Fees/Day")
self.patrons_table.SetColLabelValue( 6, "Fees Owed" )
self.patrons_table.SetColLabelAlignment( wx.ALIGN_CENTRE, wx.ALIGN_CENTRE )
# Rows
self.patrons_table.AutoSizeRows()
self.patrons_table.EnableDragRowSize( True )
self.patrons_table.SetRowLabelSize( 80 )
self.patrons_table.SetRowLabelAlignment( wx.ALIGN_CENTRE, wx.ALIGN_CENTRE )
# Label Appearance
# Cell Defaults
self.patrons_table.SetDefaultCellAlignment( wx.ALIGN_LEFT, wx.ALIGN_TOP )
self.patrons_table.SetToolTipString( u"Table of patrons in the library" )
bSizer2.Add( self.patrons_table, 7, wx.EXPAND|wx.ALL|wx.ALIGN_BOTTOM, 5 )
bSizer6 = wx.BoxSizer( wx.VERTICAL )
self.m_panel1 = wx.Panel( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
bSizer6.Add( self.m_panel1, 1, wx.EXPAND |wx.ALL, 5 )
self.m_button1 = wx.Button( self, wx.ID_ANY, u"Add", wx.DefaultPosition, wx.DefaultSize, 0 )
self.m_button1.SetToolTipString( u"Adds a patron" )
bSizer6.Add( self.m_button1, 0, wx.ALL, 5 )
self.m_button2 = wx.Button( self, wx.ID_ANY, u"Remove", wx.DefaultPosition, wx.DefaultSize, 0 )
self.m_button2.SetToolTipString( u"Removes the selected patron" )
bSizer6.Add( self.m_button2, 0, wx.ALL, 5 )
self.m_button3 = wx.Button( self, wx.ID_ANY, u"Update", wx.DefaultPosition, wx.DefaultSize, 0 )
self.m_button3.SetToolTipString( u"Updates the database" )
bSizer6.Add( self.m_button3, 0, wx.ALL, 5 )
bSizer2.Add( bSizer6, 1, wx.EXPAND, 5 )
bSizer1.Add( bSizer2, 1, wx.EXPAND, 5 )
bSizer5 = wx.BoxSizer( wx.HORIZONTAL )
self.m_searchCtrl2 = wx.SearchCtrl( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.Size( 715,-1 ), 0 )
self.m_searchCtrl2.ShowSearchButton( True )
self.m_searchCtrl2.ShowCancelButton( False )
bSizer5.Add( self.m_searchCtrl2, 0, wx.ALL|wx.EXPAND, 5 )
bSizer1.Add( bSizer5, 0, wx.EXPAND, 5 )
self.SetSizer( bSizer1 )
self.Layout()
self.Centre( wx.BOTH )
# Connect Events
self.patrons_table.Bind( wx.grid.EVT_GRID_CELL_CHANGE, self.onGridChange )
self.patrons_table.Bind( wx.grid.EVT_GRID_SELECT_CELL, self.onLeftClick )
self.m_button1.Bind( wx.EVT_BUTTON, self.addpatron )
self.m_button2.Bind( wx.EVT_BUTTON, self.removepatron )
self.m_button3.Bind( wx.EVT_BUTTON, self.updatepatronsDatabase )
self.m_searchCtrl2.Bind( wx.EVT_SEARCHCTRL_SEARCH_BTN, self.searchpatrons )
self.m_searchCtrl2.Bind( wx.EVT_TEXT_ENTER, self.searchpatrons )
#Import the Database into the table
self.lib = Library()
self.db = Database()
for i in self.db.getPatrons():
print "hello"
self.lib.addPatron(Patron(i[0], i[1], i[2], i[3], i[4]))
self.lib.resetHistory()
for i in self.lib.patrons:
self.patrons_table.InsertRows()
self.patrons_table.SetCellValue(0,0,str(i["title"]))
self.patrons_table.SetCellValue(0,1,str(i["author"]))
self.patrons_table.SetCellValue(0,2,str(i["patron_id"]))
self.patrons_table.SetCellValue(0,3,str(i["location"]))
self.patrons_table.SetCellValue(0,4,str(i["publisher"]))
self.patrons_table.SetCellValue(0,5,str(i["genre"]))
self.patrons_table.SetCellValue(0,6,str(i["copy_right"]))
self.patrons_table.SetCellValue(0,7,str(i["subject"]))
self.patrons_table.SetCellValue(0,8,str(i["is_checked_out"]))
def __del__( self ):
pass
# Virtual event handlers, overide them in your derived class
#EVENTS
def onGridChange( self, event ):# Called if one of the cell values was changed
updated_patron = Patron(self.patrons_table.GetCellValue(self.patrons_table.GetGridCursorRow(),0),
self.patrons_table.GetCellValue(self.patrons_table.GetGridCursorRow(),1),
self.patrons_table.GetCellValue(self.patrons_table.GetGridCursorRow(),2),
self.patrons_table.GetCellValue(self.patrons_table.GetGridCursorRow(),3),
self.patrons_table.GetCellValue(self.patrons_table.GetGridCursorRow(),4),
self.patrons_table.GetCellValue(self.patrons_table.GetGridCursorRow(),5),
self.patrons_table.GetCellValue(self.patrons_table.GetGridCursorRow(),6),
self.patrons_table.GetCellValue(self.patrons_table.GetGridCursorRow(),7),
self.patrons_table.GetCellValue(self.patrons_table.GetGridCursorRow(),8),
self.patrons_table.GetCellValue(self.patrons_table.GetGridCursorRow(),9),
self.patrons_table.GetCellValue(self.patrons_table.GetGridCursorRow(),10))
self.lib.editPatron(self.selected_patron, updated_patron)
def onLeftClick( self, event ): #Turns the selected row into a patron
self.selected_patron = Patron(self.patrons_table.GetCellValue(self.patrons_table.GetGridCursorRow(),0),
self.patrons_table.GetCellValue(self.patrons_table.GetGridCursorRow(),1),
self.patrons_table.GetCellValue(self.patrons_table.GetGridCursorRow(),2),
self.patrons_table.GetCellValue(self.patrons_table.GetGridCursorRow(),3),
self.patrons_table.GetCellValue(self.patrons_table.GetGridCursorRow(),4),
self.patrons_table.GetCellValue(self.patrons_table.GetGridCursorRow(),5),
self.patrons_table.GetCellValue(self.patrons_table.GetGridCursorRow(),6),
self.patrons_table.GetCellValue(self.patrons_table.GetGridCursorRow(),7),
self.patrons_table.GetCellValue(self.patrons_table.GetGridCursorRow(),8),
self.patrons_table.GetCellValue(self.patrons_table.GetGridCursorRow(),9),
self.patrons_table.GetCellValue(self.patrons_table.GetGridCursorRow(),10))
self.row = self.patrons_table.GetGridCursorRow()
self.column = self.patrons_table.GetGridCursorCol()
event.Skip()
def addpatron( self, event ):# adds a patron to the library and the table
self.patrons_table.InsertRows()
self.lib.addpatron(Patron())
event.Skip()
def removepatron( self, event ): #removes a patron from the table and the library
self.lib.removepatron(self.selected_patron)
self.patrons_table.DeleteRows()
print self.lib.patrons
event.Skip()
def updatepatronsDatabase( self, event ): #syncs the database with the library
self.db.mergeWithLibrary(self.lib)
def searchpatrons( self, event ):
value = self.m_searchCtrl2.GetValue()
i=0
while self.patrons_table.GetNumberRows()-1 >i:
if self.patrons_table.GetCellValue(i,2) == value:
self.patrons_table.SetGridCursor(i,2)
self.patrons_table.SelectRow(i)
self.patrons_table.Scroll(i,i)
break
i = i+1
if __name__ == '__main__':
app = wx.PySimpleApp()
frame = MyFrame1(None)
frame.Show()
frame.Maximize()
app.MainLoop()
而代码的第二部分是GUI类背后的引擎:
'''
Created on Mar 2, 2013
@author: Braden
This is a test file to try to make the GUI easier to program
It worked!
'''
import sqlite3 as sq
class Book(object):
r"""
This class defines what a book is. All books in the library are book objects
"""
def __init__(self, title = "n", author = "n", book_id = "n", location = "n", publisher = "n", genre = "n", copy_right = "n", subject = "n", is_checked_out = "n", price = "n", fee_increment = "n"):
r"""
This function sets the basic attributes of each book
"""
self.attributes = {"title":title,
"author":author,
"book_id":book_id,
"location":location,
"publisher":publisher,
"genre":genre,
"copy_right":copy_right,
"subject": subject,
"is_checked_out":is_checked_out,
"price": price,
"fee_increment":fee_increment
}
def __str__(self):
r"""
This returns a string representation of the book. This is what makes " print book" possible.
"""
return str(self.attributes)
def __getitem__(self,key):
r"""
This returns an attribute in the book. It makes "book['title']" work.
"""
return self.attributes[key]
def __setitem__(self,key,value):
r"""
This sets an attribute to a different value. It makes "book['title'] = 'My New Title' " Possilble ...I think.
"""
self.attributes[key] = value
def __cmp__(self,book):
if self.attributes == book.attributes:
return True
else:
return False
class Patron(object):
r"""
This is the Patron class. It is almost identical to the Book class just with different attributes.
"""
def __init__(self, patron_id, name, address, phone, email):
self.attributes = { "patron_id" : patron_id,
"name" : name,
"address" : address,
"phone" : phone,
"email" : email,
"fee_balance" : 0.00,
"fees_per_day" : 0.00,
"books_checked_out" : "",
"books_overdue" : ""}
def __str__(self):
return str(self.attributes)
def __getitem__(self,key):
return self.attributes[key]
def __setitem__(self,key,value):
self.attributes[key] = value
class Library(object):
r"""
This is the Library Class. It manipulates a database that has been loaded into the RAM.
"""
def __init__(self):
r"""
All this does is set the default values for the two Loaded Databases and the history.
"""
self.books = []
self.patrons= []
self.history = []
def addBook(self,book):
r"""
This appends a book object to the self.books list. Then it appends the action to the self.history list.
"""
self.books.append(book)
self.history.append(("book","add",book))
def removeBook(self, Book):
r"""
This removes a book object from the self.books list. Then it appends the action to the self.history list
"""
self.books.remove(Book)
self.history.append(("book","remove",Book))
def editBook(self, old_book, new_book):
original_id = old_book["book_id"]
r"""
This edits a book object in the self.books list. Then it appends the action to the self.history list.
"""
old_book["title"] = new_book["title"]
old_book["author"] = new_book["author"]
old_book["book_id"] = new_book["book_id"]
old_book["location"] = new_book["location"]
old_book["publisher"] = new_book["publisher"]
old_book["genre"] = new_book["genre"]
old_book["copy_right"] = new_book["copy_right"]
old_book["subject"] = new_book["subject"]
old_book["is_checked_out"] = new_book["is_checked_out"]
old_book["price"] = new_book["price"]
old_book["fee_increment"] = new_book["fee_increment"]
self.history.append(("book","edit",old_book,original_id))
def addPatron(self, patron):
r"""
This appends a new Patron object to the self.patrons list. It then appends the action to the self.history list.
"""
self.patrons.append(patron)
self.history.append(("patron","add",patron))
print "bonjour"
print self.patrons[0]
def removePatron(self,patron):
r"""
This Removes a patron object from the self.patrons list. It then appends the actino to the self.history list.
"""
self.patrons.remove(patron)
self.history.append(("patron","remove",patron))
def editPatron(self,patron,attribute,value):
r"""
This edits a patron object in the self.patrons list. It then appends the action to the self.history list.
"""
patron[attribute] = value
self.history.append(("patron","edit",patron))
def resetHistory(self):
r"""
This resets the self.history list
"""
self.history=[]
def getBook(self,book_id):
r"""
This finds a book based on its id
"""
for i in self.books:
if i["book_id"] == str(book_id):
return i
def __str__(self):
for i in self.books:
print i
for i in self.patrons:
print i
return "done"
class Database():
r"""
This is the Database Class. It modifies the library.db file.
"""
def __init__ (self):
r"""
This presets the self.database variable and the self.cursor variable
"""
self.database = sq.connect('library.db')
self.cursor = self.database.cursor()
def mergeWithLibrary(self,library):
r"""
This is my personal favorite. It updates the library.db file based off of the changes the Library object.
"""
for i in library.history:
print i
if i[0] == "book":
if i[1] == "add":
self.addBook(i[2])
elif i[1] == "remove":
self.deleteBook(i[2])
elif i[1] == "edit":
self.editBook(i[2],i[3])
elif i[0] == "patron":
if i[1] == "add":
self.addPatron(i[2])
elif i[1] == "remove":
self.deletePatron(i[2])
elif i[2] == "edit":
self.editPatron(i[2])
library.resetHistory()
def getBooks(self):
r"""
This returns all of the books in the library.db database
"""
self.cursor.execute("SELECT * FROM books")
return self.cursor.fetchall()
def getPatrons(self):
r"""
This returns all of the Patrons in the library.db database
"""
self.cursor.execute("SELECT * FROM patrons")
print self.cursor.fetchall()
print "called"
return [(0,0,0,0,0,0,0,0,0,0,0,0)]
def editBook(self,Book,id):
r"""
This updates a Book
"""
self.cursor.execute("UPDATE books SET title = '"+Book["title"]+"', author = '"+Book["author"]+"', book_id= '"+Book["book_id"]+"', location = '"+Book["location"]+"', publisher = '"+Book["publisher"]+"', genre = '"+Book["genre"]+"', copy_right = '"+Book["copy_right"]+"', subject = '"+Book["subject"]+"', is_checked_out = '"+Book["is_checked_out"]+"', price = '"+Book["price"]+"', fee_increment = '"+Book["fee_increment"]+"' WHERE book_id = '"+id+"'")
self.database.commit()
print Book["fee_increment"]
def editPatron(self,Patron):
r"""
This edits a Patron
"""
self.cursor.execute("UPDATE patrons SET name= '"+Patron["name"]+"', address = '"+Patron["address"]+"', phone = '"+str(Patron["phone"])+"', email = '"+Patron["email"]+"', fee_balance = '"+str(Patron["fee_balance"])+"', fees_per_day = '"+str(Patron["fees_per_day"])+"', books_checked_out = '"+Patron["books_checked_out"]+"', books_overdue = '" +Patron["books_overdue"]+"' WHERE id ="+str(Patron["patron_id"]))
self.database.commit()
def deleteBook(self,Book):
r"""
This deletes a book
"""
self.cursor.execute("DELETE FROM books WHERE book_id = "+"'"+Book["book_id"]+"'")
self.database.commit()
def deletePatron(self,Patron):
r"""
"""
self.cursor.execute("DELETE FROM patrons WHERE id = "+"'"+str(Patron["patron_id"])+"'")
self.database.commit()
def addBook(self,Book):
r"""
This adds a book
"""
data = [
Book["title"],
Book["author"],
Book["book_id"],
Book["location"],
Book["publisher"],
Book["genre"],
Book["copy_right"],
Book["subject"],
Book["is_checked_out"],
Book["price"],
Book["fee_increment"]
]
self.cursor.execute("INSERT INTO books VALUES(?,?,?,?,?,?,?,?,?,?,?)", data)
self.database.commit()
def addPatron(self,Patron):
r"""
This adds a Patron
"""
data = [Patron["patron_id"],
Patron["name"],
Patron["address"],
Patron["phone"],
Patron["email"],
Patron["fee_balance"],
Patron["fees_per_day"],
Patron["books_checked_out"],
Patron["books_overdue"]]
self.cursor.execute("INSERT INTO patrons VALUES(?,?,?,?,?,?,?,?,?)",data)
self.database.commit()
每次我运行我的代码时,我所有的小print
语句标志都会在控制台中弹出,但是窗口没有打开,然后 python 崩溃了。注释掉for
我将数据库导入表的语句可以让程序运行,但是任何调用self.lib.addPatron
都会再次使程序崩溃。我认为该功能没有问题,我只是愚蠢吗?