wxPython objectListView сохранить изменения
Я пытаюсь научиться использовать objectListView в wxPython. При запуске примера из Mouse vs. Python. Я вижу, что вы можете редактировать ячейку, но после закрытия программы редактирование не сохраняется. Я смотрел на документацию от readthedocs в течение 2 дней и не смог заставить ее работать. Как вы разрешаете редактировать и сохранять его?
Есть ли возможность построить строки из файла CSV и обновить редактирование файла CSV?
Я использую wxPython Phoenix 3.0.3 и Python 2.7
Вот мой стартовый код:
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)
Моя цель - позволить пользователю изменить значение в любом столбце. В документации по редактированию значений ячеек я вижу, что первым шагом является установка атрибута cellEditMode. Следующим шагом является выбор редактора ячеек, и это то, где я запутался. Если я хочу, чтобы пользователь мог редактировать любую ячейку, должен ли я использовать столбец, события или редактор реестра? Где происходит "Получение" и "Настройка"? Могу ли я использовать GetValue и SetValue без создания редактора ячеек? Затем объект модели должен быть обновлен; это можно сделать, просто покинув ячейку, или же должно происходить что-то активное, например, привязка функции к кнопке?
Из примеров, которые предоставляет Майк Дрисколл, я вижу, как он обновляет список, но изменения не сохраняются. После закрытия графического интерфейса изменения теряются. Как сохранить изменения?
1 ответ
Без использования каких-либо csv
модули, которые могут сделать вашу жизнь проще и предполагают местный book.txt
файл, который выглядит следующим образом:
"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"
Следующее даст вам упрощенное представление о том, как достичь вашей цели, используя пример кода Майка Дрисколла
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()