wxPython objectListView save changes

521 Views Asked by At

I am trying to learn to use objectListView in wxPython. When running the example from Mouse vs.Python. I see that you can edit a cell but once the program is closed, the edit is not saved. I have stared at the documentation from readthedocs for 2 days and I have been unable to make it work. How do you allow an edit and save it?

Is there away to build the rows from a CSV file and have the edit update the CSV file?

I am using wxPython Phoenix 3.0.3 and Python 2.7

Here is my starter code:

class Book(object):
def __init__(self, cue, sendTo, red, green, blue, time):
    self.cue = cue
    self.sendTo = sendTo
    self.red = red
    self.green = green
    self.blue = blue
    self.time = time
class MainFrame(wx.Frame):
def __init__(self, parent, id, title):
    wx.Frame.__init__(self, parent=None, id=wx.ID_ANY, 
                      title="ObjectListView", size=(800,600))


    panel = wx.Panel(self, -1)

    #Need to get this information from *.txt file
    self.cues = [Book("cue 1", "NodeA",
                      "193", "123", "123","0"),
                 Book("cue 2", "Group 1",
                      "193", "123", "123","0")
                 ]

    self.cuesOlv = ObjectListView(panel, wx.ID_ANY, style=wx.LC_REPORT|wx.SUNKEN_BORDER)
    self.setCues()
    self.cuesOlv.cellEditMode = ObjectListView.CELLEDIT_SINGLECLICK


    mainSizer = wx.BoxSizer(wx.VERTICAL)

    mainSizer.Add(self.cuesOlv, 1, wx.ALL|wx.EXPAND, 5)
    #mainSizer.Add(self.updateBtn, 0, wx.ALL|wx.CENTER, 5)
    panel.SetSizer(mainSizer)

def setCues(self, data=None):
    self.cuesOlv.SetColumns([
        ColumnDefn("Cue", "center", 100, "cue"),
        ColumnDefn("Send To:", "center", 100, "sendTo"),
        ColumnDefn("Red", "center", 100, "red"),            
        ColumnDefn("Green", "center", 100, "green"),
        ColumnDefn("Blue", "center", 100, "blue"),
        ColumnDefn("Time", "center", 100, "time")
    ])

    self.cuesOlv.SetObjects(self.cues)

My goal is to allow the user to change a value in any column. In the documentation on Editing Cell Values, I see that the first step is setting the cellEditMode attribute. The next step is to decide on a cell editor and that is where I am confused. If I want the user to be able to edit any cell should I use the column based, event based or the registry based editor? Where does 'Getting' and 'Setting' come in? Can I use GetValue and SetValue without creating a cell editor? Then the Model Object must be updated; can that be done just by leaving the cell or does something active have to take place like binding a function to a button?

From the examples Mike Driscoll provides, I see how he updates the list but the changes are not saved. Once the GUI is closed, the changes are lost. How do you save the changes?

1

There are 1 best solutions below

0
On

Without using any csv modules, which might make your life easier and assuming a local book.txt file, which is as follows:

"wxPython in Action","Robin Dunn","1932394621","Manning"
"Hello World","Warren and Carter Sande","1933988495","Manning"
"Core Python Programming","Wesley Chun","0132269937","Prentice Hall"
"Python Programming for the Absolute Beginner","Michael Dawson","1598631128","Course Technology"
"Learning Python","Mark Lutz","0596513984","O'Reilly"

The following will give you a simplistic idea of how to achieve your objective, using Mike Driscoll's example code

import wx
from ObjectListView import ObjectListView, ColumnDefn

########################################################################
class Book(object):
    """
    Model of the Book object

    Contains the following attributes:
    'ISBN', 'Author', 'Manufacturer', 'Title'
    """
    #----------------------------------------------------------------------
    def __init__(self, title, author, isbn, mfg):
        self.isbn = isbn
        self.author = author
        self.mfg = mfg
        self.title = title

########################################################################
class MainPanel(wx.Panel):
    #----------------------------------------------------------------------
    def __init__(self, parent):
        wx.Panel.__init__(self, parent=parent, id=wx.ID_ANY)
        #Read the book data from a file
        with open('books.txt','r') as f:
            books = f.readlines()
        self.products = []
        #Manually strip out inverted commas and line feeds, then split the data into its parts
        for b in books:
            b=b.replace('"','')
            b=b.strip()
            title,author,isbn,pub = b.split(",")
            self.products.append(Book(title,author,isbn,pub))
        self.dataOlv = ObjectListView(self, wx.ID_ANY, style=wx.LC_REPORT|wx.SUNKEN_BORDER)
        self.setBooks()

        # Allow the cell values to be edited when double-clicked
        self.dataOlv.cellEditMode = ObjectListView.CELLEDIT_SINGLECLICK

        # create an Write output file button
        updateBtn = wx.Button(self, wx.ID_ANY, "Write Output")
        updateBtn.Bind(wx.EVT_BUTTON, self.updateControl)
        # Create some sizers
        mainSizer = wx.BoxSizer(wx.VERTICAL)        
        mainSizer.Add(self.dataOlv, 1, wx.ALL|wx.EXPAND, 5)
        mainSizer.Add(updateBtn, 0, wx.ALL|wx.CENTER, 5)
        self.SetSizer(mainSizer)

    #----------------------------------------------------------------------
    def updateControl(self, event):
        """
        Write OLV data to a file 
        """
        #retrieve the data from the Olv
        data=self.dataOlv.GetObjects()
        #Write the data out to an empty file
        with open('books1.txt','w') as f:
            for b in data:
                outp='"%s","%s","%s","%s"\n'%(b.title,b.author,b.isbn,b.mfg)
                f.write(outp)

    #----------------------------------------------------------------------
    def setBooks(self, data=None):
        self.dataOlv.SetColumns([
            ColumnDefn("Title", "left", 220, "title"),
            ColumnDefn("Author", "left", 200, "author"),
            ColumnDefn("ISBN", "right", 100, "isbn"),            
            ColumnDefn("Mfg", "left", 180, "mfg")
        ])
        self.dataOlv.SetObjects(self.products)

########################################################################
class MainFrame(wx.Frame):
    #----------------------------------------------------------------------
    def __init__(self):
        wx.Frame.__init__(self, parent=None, id=wx.ID_ANY, 
                          title="ObjectListView Demo", size=(800,600))
        panel = MainPanel(self)

########################################################################
class GenApp(wx.App):

    #----------------------------------------------------------------------
    def __init__(self, redirect=False, filename=None):
        wx.App.__init__(self, redirect, filename)

    #----------------------------------------------------------------------
    def OnInit(self):
        # create frame here
        frame = MainFrame()
        frame.Show()
        return True

#----------------------------------------------------------------------
def main():
    """
    Run the demo
    """
    app = GenApp()
    app.MainLoop()

if __name__ == "__main__":
    main()