0

所以,我有两段代码。首先是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都会再次使程序崩溃。我认为该功能没有问题,我只是愚蠢吗?

4

2 回答 2

0

当调试 WXpython 程序在给你任何有用的输出之前崩溃时,你可以通过在启动应用程序时指定重定向来将错误保存到日志文件中。因此,将启动应用程序的行更改为:

app = wx.pySimpleApp(redirect=True,  filename="logfile.txt") 

会将您的错误保存到与脚本位于同一文件夹中的日志文件中,然后您将更好地了解正在发生的事情。

于 2013-03-08T07:40:46.360 回答
0

如果您向我们提供您所获得的追溯信息,那将会有所帮助。当我运行此代码时,我得到以下信息:

  sqlite3.OperationalError: no such table: patrons
  File "c:\Users\mdriscoll\Desktop\brk.py", line 191, in <module>
    frame = MyFrame1(None)
  File "c:\Users\mdriscoll\Desktop\brk.py", line 115, in __init__
    for i in self.db.getPatrons():
  File "c:\Users\mdriscoll\Desktop\Books.py", line 184, in getPatrons
    self.cursor.execute("SELECT * FROM patrons")

既然您声明您也在“self.lib.addPatron”上遇到问题,那么这意味着这可能是同一个问题。正如回溯所示,该表不存在。您需要先创建表(即使它们是空的),然后才能添加任何内容来执行它们。本文可能会帮助您入门: http: //www.blog.pythonlibrary.org/2012/07/18/python-a-simple-step-by-step-sqlite-tutorial/

于 2013-03-07T14:29:12.780 回答