Как изменить значение строки существующего элемента в wxPython ObjectListView list_ctrl
Я знаю, что могу использовать list_ctrl.GetStringValueAt()
так, чтобы получить значение для конкретного объекта в ObjectListView
:
class myOLV(ObjectListView):
... code to handle specific events
class myPanel(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
self.list_ctrl = myOLV(self, wx.ID_ANY, style=wx.LC_REPORT)
self.setColumns()
# . . .
self.submit_button = wx.Button(self, label="Submit")
# ... add to sizer here, skipping tedious stuff in this example
self.submit_button.Bind(wx.EVT_BUTTON, self.onSubmit)
def setColumns(self):
self.list_ctrl.SetColumns([
ColumnDefn("Column 1", "left", 128, "col1"),
ColumnDefn("Column 2", "left", 128, "col2"),
ColumnDefn("Column 3", "left", 128, "col3")
)]
def onSubmit(self, event):
objects = self.list_ctrl.GetObjects()
for obj in objects:
col1 = self.list_ctrl.GetStringValueAt(obj, 1)
# how could I change the above value here?
col2 = self.list_ctrl.GetStringValueAt(obj, 2)
col3 = self.list_ctrl.GetStringValueAt(obj, 3)
Но что если я захочу изменить значение строки, заданной в этом текущем цикле и индексе столбца? В документации, похоже, нет метода, который принимает текущий объект и индекс столбца в качестве параметра, так как я могу это сделать (не удаляя и не заполняя элемент)?
Я вижу из документов, что есть SetValue(modelObjects, preserveSelection=False)
метод, но он устанавливает список modelObjects для отображения элемента управления, а это не то, что я пытаюсь сделать.
Есть ли SetStringValueAt(modelObject, columnIndex)
метод или обходной путь, чтобы сделать то же самое в этом контексте?
1 ответ
Вы можете включить "редактируемость" ячейки, установив свой экземпляр ObjectListView cellEditMode
, Примерно так будет работать:
self.list_ctrl.cellEditMode = ObjectListView.CELLEDIT_SINGLECLICK
Документация ObjectListView говорит об этом здесь:
- http://objectlistview.sourceforge.net/python/cellEditing.html (старые документы)
- http://objectlistview-python-edition.readthedocs.org/en/latest/cellEditing.html (новые документы)
Я также упоминаю об этом в следующем уроке:
ОБНОВЛЕНИЕ: перебирать объекты и изменять их программно немного сложнее. К счастью, ObjectListView обеспечивает RefreshObject
, что позволяет нам изменить конкретный объект, а затем обновить его. Вот пример сценария:
# OLVcheckboxes.py
import wx
from ObjectListView import ObjectListView, ColumnDefn
########################################################################
class Results(object):
""""""
#----------------------------------------------------------------------
def __init__(self, tin, zip_code, plus4, name, address):
"""Constructor"""
self.tin = tin
self.zip_code = zip_code
self.plus4 = plus4
self.name = name
self.address = address
########################################################################
class ProvPanel(wx.Panel):
""""""
#----------------------------------------------------------------------
def __init__(self, parent):
"""Constructor"""
wx.Panel.__init__(self, parent=parent)
mainSizer = wx.BoxSizer(wx.VERTICAL)
self.columns = {0: 'tin',
1: 'zip_code',
2: 'plus4',
3: 'name',
4: 'address'}
self.test_data = [Results("123456789", "50158", "0065", "Patti Jones",
"111 Centennial Drive"),
Results("978561236", "90056", "7890", "Brian Wilson",
"555 Torque Maui"),
Results("456897852", "70014", "6545", "Mike Love",
"304 Cali Bvld")
]
self.resultsOlv = ObjectListView(self, style=wx.LC_REPORT|wx.SUNKEN_BORDER)
self.resultsOlv.cellEditMode = ObjectListView.CELLEDIT_SINGLECLICK
self.setResults()
self.column_cbo = wx.ComboBox(self, value='tin',
choices=self.columns.values())
modify_btn = wx.Button(self, label='Modify Column 1 Cells')
modify_btn.Bind(wx.EVT_BUTTON, self.onModify)
mainSizer.Add(self.resultsOlv, 1, wx.EXPAND|wx.ALL, 5)
mainSizer.Add(self.column_cbo, 0, wx.CENTER|wx.ALL, 5)
mainSizer.Add(modify_btn, 0, wx.CENTER|wx.ALL, 5)
self.SetSizer(mainSizer)
#----------------------------------------------------------------------
def onModify(self, event):
"""
Modify cells
"""
objects = self.resultsOlv.GetObjects()
column = self.column_cbo.GetValue()
for obj in objects:
value = 'Row #%s' % self.resultsOlv.GetIndexOf(obj)
setattr(obj, column, value)
self.resultsOlv.RefreshObject(obj)
#----------------------------------------------------------------------
def setResults(self):
""""""
self.resultsOlv.SetColumns([
ColumnDefn("TIN", "left", 100, "tin"),
ColumnDefn("Zip", "left", 75, "zip_code"),
ColumnDefn("+4", "left", 50, "plus4"),
ColumnDefn("Name", "left", 150, "name"),
ColumnDefn("Address", "left", 200, "address")
])
self.resultsOlv.CreateCheckStateColumn()
self.resultsOlv.SetObjects(self.test_data)
########################################################################
class ProvFrame(wx.Frame):
""""""
#----------------------------------------------------------------------
def __init__(self):
"""Constructor"""
title = "OLV Checkbox Tutorial"
wx.Frame.__init__(self, parent=None, title=title, size=(1024, 768))
panel = ProvPanel(self)
#----------------------------------------------------------------------
if __name__ == "__main__":
app = wx.App(False)
frame = ProvFrame()
frame.Show()
app.MainLoop()