Strange bug in editing EditableListCtrl

Hi all,
let’s me explain my situation.
I have an EditableListCtrl in a panel and I would have a list with two colums.
In particular, the item in the first column can not be modified.
At the bottom of this post there is a little pice of code.

I’m able to create and populate the list and also to edit the items in the second colum.
Anyway, I am facing a strange bug:
if it is the first time that I try to edit the list and I try to edit the second column of the first item, I’m not able to correctly menage this situation.
In fact, in this case I get -1 in the variable “focusedRow” of the OnItemEdited function.
I have no problem when I try to modify whatever items belonging to the second column of whaterver row, except the first one.
If I edit a row different from the first one, then I have no problem with the first row.

I’m using wxpython 3.0.2.0 and python 2.7.10.

Any idea?

Thank you vevry much.
Robert

class EditableListCtrl(wx.ListCtrl, listmix.CheckListCtrlMixin, listmix.TextEditMixin):
def init(self, parent, ID=wx.ID_ANY, pos=wx.DefaultPosition, size=wx.DefaultSize, style=0):

    wx.ListCtrl.__init__(self, parent, ID, pos, size, style)
    listmix.TextEditMixin.__init__(self)
    listmix.CheckListCtrlMixin.__init__(self)
   
    self.parent = parent

def OnCheckItem(self, index, flag):
    event = self.parent.CheckModifyEvent(ind=index, flagCheck=flag)
    wx.PostEvent(self.parent, event)

class something():
# OTHER CODE

def ShowPanel(self):
    self.Panel = wx.Dialog(self.parent, style = wx.ID_OK|wx.DEFAULT_DIALOG_STYLE)
    self.Panel.CheckModifyEvent, self.Panel.EVT_CHECKMODIFY = wx.lib.newevent.NewEvent()
   
    self.ListCtrl = EditableListCtrl(self.Panel, style=wx.LC_REPORT|wx.BORDER_SUNKEN)
    self.ListCtrl.InsertColumn(0, 'Col 1')
    self.ListCtrl.InsertColumn(1, 'Col 2')
   
    self.ListCtrl.Bind(wx.EVT_LIST_END_LABEL_EDIT, self.OnItemEdited)
    self.ListCtrl.Bind(wx.EVT_LIST_BEGIN_LABEL_EDIT, self.OnStartingEditing)
   
    for i, itemForList in enumerate(self.itemsForList):
        self.ListCtrl.InsertStringItem(i, itemForList[0])
        self.ListCtrl.SetStringItem(i, 1, itemForList[1])
   
    # OTHER CODE FOR VISUALIZATION
       
 def OnStartingEditing(self, evt):
    if evt.m_col == 0:
        evt.Veto()
    else:
        evt.Skip()

def OnItemEdited(self, evt):
    focusedRow = int(self.ListCtrl.GetFocusedItem())

    if evt.GetLabel() != "":
        self.ListCtrl.ToggleItem(focusedRow)
        # DO SOME OTHER STUFF

``

···

where from did u import listmix ?

At the top of the file I import it in this way:
import wx.lib.mixins.listctrl as listmix

···

where from did u import listmix ?

if you get your mod to work from below src, I could try to replicate the issue. Thx.

'''
/usr/local/lib/python2.7/dist-packages/wx/lib/mixins/listctrl.py

modded
'''

import wx
import wx.lib.mixins.listctrl as listmix

class sssEditableListCtrl(wx.ListCtrl, listmix.CheckListCtrlMixin, listmix.TextEditMixin):
     def __init__(self, parent, ID=wx.ID_ANY, pos=wx.DefaultPosition, size=wx.DefaultSize, style=0):
         wx.ListCtrl.__init__(self, parent, ID, pos, size, style)
         listmix.TextEditMixin.__init__(self)
         listmix.CheckListCtrlMixin.__init__(self)
         self.parent = parent

     def OnCheckItem(self, index, flag):
         event = self.parent.CheckModifyEvent(ind=index, flagCheck=flag)
         wx.PostEvent(self.parent, event)

'''
class something():
     # OTHER CODE

     def ShowPanel(self):
         self.Panel = wx.Dialog(self.parent, style = wx.ID_OK|wx.DEFAULT_DIALOG_STYLE)
         self.Panel.CheckModifyEvent, self.Panel.EVT_CHECKMODIFY = wx.lib.newevent.NewEvent()

         self.ListCtrl = EditableListCtrl(self.Panel, style=wx.LC_REPORT|wx.BORDER_SUNKEN)
         self.ListCtrl.InsertColumn(0, 'Col 1')
         self.ListCtrl.InsertColumn(1, 'Col 2')

         self.ListCtrl.Bind(wx.EVT_LIST_END_LABEL_EDIT, self.OnItemEdited)
         self.ListCtrl.Bind(wx.EVT_LIST_BEGIN_LABEL_EDIT, self.OnStartingEditing)

         for i, itemForList in enumerate(self.itemsForList):
             self.ListCtrl.InsertStringItem(i, itemForList[0])
             self.ListCtrl.SetStringItem(i, 1, itemForList[1])

         # OTHER CODE FOR VISUALIZATION

     def OnStartingEditing(self, evt):
        if evt.m_col == 0:
            evt.Veto()
        else:
            evt.Skip()

     def OnItemEdited(self, evt):
         focusedRow = int(self.ListCtrl.GetFocusedItem())

         if evt.GetLabel() != "":
             self.ListCtrl.ToggleItem(focusedRow)
             # DO SOME OTHER STUFF

'''

''' TextEditMixin allows any column to be edited. ''' # Constructor __init__
class EditableListCtrlOHNE(wx.ListCtrl, listmix.TextEditMixin):
     def __init__(self, parent, ID=wx.ID_ANY, pos=wx.DefaultPosition, size=wx.DefaultSize, style=0):
         wx.ListCtrl.__init__(self, parent, ID, pos, size, style)
         listmix.TextEditMixin.__init__(self)

class EditableListCtrlGUT(wx.ListCtrl, listmix.TextEditMixin,listmix.CheckListCtrlMixin):
     def __init__(self, parent, ID=wx.ID_ANY, pos=wx.DefaultPosition, size=wx.DefaultSize, style=0):
         wx.ListCtrl.__init__(self, parent, ID, pos, size, style)
         listmix.TextEditMixin.__init__(self)
         listmix.CheckListCtrlMixin.__init__(self)

class MyPanel(wx.Panel):
     def __init__(self, parent):
         wx.Panel.__init__(self, parent)

         '''
         #no workie inserted mod
         self.Panel = wx.Dialog(self.parent, style = wx.ID_OK|wx.DEFAULT_DIALOG_STYLE)
         self.Panel.CheckModifyEvent, self.Panel.EVT_CHECKMODIFY = wx.lib.newevent.NewEvent()

         self.ListCtrl = sssEditableListCtrl(self.Panel, style=wx.LC_REPORT|wx.BORDER_SUNKEN)
         self.ListCtrl.InsertColumn(0, 'Col 1')
         self.ListCtrl.InsertColumn(1, 'Col 2')

         self.ListCtrl.Bind(wx.EVT_LIST_END_LABEL_EDIT, self.OnItemEdited)
         self.ListCtrl.Bind(wx.EVT_LIST_BEGIN_LABEL_EDIT, self.OnStartingEditing)

         for i, itemForList in enumerate(self.itemsForList):
             self.ListCtrl.InsertStringItem(i, itemForList[0])
             self.ListCtrl.SetStringItem(i, 1, itemForList[1])

         # OTHER CODE FOR VISUALIZATION

     def OnStartingEditing(self, evt):
        if evt.m_col == 0:
            evt.Veto()
        else:
            evt.Skip()

     def OnItemEdited(self, evt):
         focusedRow = int(self.ListCtrl.GetFocusedItem())

         if evt.GetLabel() != "":
             self.ListCtrl.ToggleItem(focusedRow)
             # DO SOME OTHER STUFF

no workie
         '''

         rows = [(" ","Ford", "Capri", "1996", "Blue" ),
                 (" ","Nissan", "370Z", "2010", "Green"),
                 (" ","Porsche", "911", "2009", "Red")
                 ]
         self.list_ctrl = sssEditableListCtrl(self, style=wx.LC_REPORT)

         self.list_ctrl.InsertColumn(0, "tagged")
         self.list_ctrl.InsertColumn(1, "Make")
         self.list_ctrl.InsertColumn(2, "Model")
         self.list_ctrl.InsertColumn(3, "Year")
         self.list_ctrl.InsertColumn(4, "Color")

         index = 0
         for row in rows:
             #self.list_ctrl.InsertStringItem(index, row[0]) # depreceated
             self.list_ctrl.InsertItem(index, row[0])

             self.list_ctrl.SetItem(index, 1, row[1]) # remove String part
             self.list_ctrl.SetItem(index, 2, row[2])
             self.list_ctrl.SetItem(index, 3, row[3])
             self.list_ctrl.SetItem(index, 4, row[4])
             index += 1

         sizer = wx.BoxSizer(wx.VERTICAL)
         sizer.Add(self.list_ctrl, 0, wx.ALL|wx.EXPAND, 5)
         self.SetSizer(sizer)

class MyFrame(wx.Frame):
     def __init__(self):
         wx.Frame.__init__(self, None, wx.ID_ANY, "Editable List Control")
         panel = MyPanel(self)
         self.Show()

if __name__ == "__main__":
     app = wx.App(False)
     frame = MyFrame()
     app.MainLoop()

Sorry for the delay, I have a runnable example (see below).
If in windows you try to edit the second column of the first row you will get an error and a -1 printed on the screen.
If you try to edit another line, instead, it works fine.
After the first edit (not done on the first row) works also the editing of first line.

Any idea?

Thanks.

import wx
import wx.lib.mixins.listctrl as listmix
import wx.lib.newevent

class EditableListCtrl(wx.ListCtrl, listmix.CheckListCtrlMixin, listmix.TextEditMixin):
def init(self, parent, ID=wx.ID_ANY, pos=wx.DefaultPosition, size=wx.DefaultSize, style=0):

    wx.ListCtrl.__init__(self, parent, ID, pos, size, style)
    listmix.TextEditMixin.__init__(self)
    listmix.CheckListCtrlMixin.__init__(self)

    self.parent = parent

def OnCheckItem(self, index, flag):
    event = self.parent.CheckModifyEvent(ind=index, flagCheck=flag)
    wx.PostEvent(self.parent, event)

class MyFrame(wx.Frame):
def init(self):
wx.Frame.init(self, None)
self.itemsForList = [[‘1’, ‘a’], [‘2’, ‘b’], [‘3’, ‘c’], [‘4’, ‘d’], [‘5’, ‘e’], [‘6’, ‘f’]]
self.ShowPanel()

def ShowPanel(self):
    self.Panel = wx.Dialog(self, style = wx.ID_OK|wx.DEFAULT_DIALOG_STYLE)
    self.Panel.CheckModifyEvent, self.Panel.EVT_CHECKMODIFY = wx.lib.newevent.NewEvent()

    self.ListCtrl = EditableListCtrl(self.Panel, style=wx.LC_REPORT|wx.BORDER_SUNKEN)
    self.ListCtrl.InsertColumn(0, 'Col 1')
    self.ListCtrl.InsertColumn(1, 'Col 2')

    self.ListCtrl.Bind(wx.EVT_LIST_END_LABEL_EDIT, self.OnItemEdited)
    self.ListCtrl.Bind(wx.EVT_LIST_BEGIN_LABEL_EDIT, self.OnStartingEditing)

    for i, itemForList in enumerate(self.itemsForList):
        self.ListCtrl.InsertStringItem(i, itemForList[0])
        self.ListCtrl.SetStringItem(i, 1, itemForList[1])
    self.Panel.Show()

def OnStartingEditing(self, evt):
    if evt.m_col == 0:
        evt.Veto()
    else:
        evt.Skip()

def OnItemEdited(self, evt):
    focusedRow = int(self.ListCtrl.GetFocusedItem())

    if evt.GetLabel() != "":
        self.ListCtrl.ToggleItem(focusedRow)
        print('The index of the selected row is %d' % focusedRow)

app = wx.App(redirect=False)
top = MyFrame()
app.MainLoop()

``

···

if you get your mod to work from below src, I could try to replicate the
issue. Thx.

‘’’

/usr/local/lib/python2.7/dist-packages/wx/lib/mixins/listctrl.py

modded

‘’’

import wx

import wx.lib.mixins.listctrl as listmix

class sssEditableListCtrl(wx.ListCtrl, listmix.CheckListCtrlMixin,
listmix.TextEditMixin):

 def __init__(self, parent, ID=wx.ID_ANY, pos=wx.DefaultPosition,

size=wx.DefaultSize, style=0):

     wx.ListCtrl.__init__(self, parent, ID, pos, size, style)

     listmix.TextEditMixin.__init__(self)

     listmix.CheckListCtrlMixin.__init__(self)

     self.parent = parent



 def OnCheckItem(self, index, flag):

     event = self.parent.CheckModifyEvent(ind=index, flagCheck=flag)

     wx.PostEvent(self.parent, event)

‘’’

class something():

 # OTHER CODE



 def ShowPanel(self):

     self.Panel = wx.Dialog(self.parent, style =

wx.ID_OK|wx.DEFAULT_DIALOG_STYLE)

     self.Panel.CheckModifyEvent, self.Panel.EVT_CHECKMODIFY =

wx.lib.newevent.NewEvent()

     self.ListCtrl = EditableListCtrl(self.Panel,

style=wx.LC_REPORT|wx.BORDER_SUNKEN)

     self.ListCtrl.InsertColumn(0, 'Col 1')

     self.ListCtrl.InsertColumn(1, 'Col 2')



     self.ListCtrl.Bind(wx.EVT_LIST_END_LABEL_EDIT, self.OnItemEdited)

     self.ListCtrl.Bind(wx.EVT_LIST_BEGIN_LABEL_EDIT,

self.OnStartingEditing)

     for i, itemForList in enumerate(self.itemsForList):

         self.ListCtrl.InsertStringItem(i, itemForList[0])

         self.ListCtrl.SetStringItem(i, 1, itemForList[1])



     # OTHER CODE FOR VISUALIZATION



 def OnStartingEditing(self, evt):

    if evt.m_col == 0:

        evt.Veto()

    else:

        evt.Skip()



 def OnItemEdited(self, evt):

     focusedRow = int(self.ListCtrl.GetFocusedItem())



     if evt.GetLabel() != "":

         self.ListCtrl.ToggleItem(focusedRow)

         # DO SOME OTHER STUFF

‘’’

‘’’ TextEditMixin allows any column to be edited. ‘’’ #
Constructor init

class EditableListCtrlOHNE(wx.ListCtrl, listmix.TextEditMixin):

 def __init__(self, parent, ID=wx.ID_ANY, pos=wx.DefaultPosition,

size=wx.DefaultSize, style=0):

     wx.ListCtrl.__init__(self, parent, ID, pos, size, style)

     listmix.TextEditMixin.__init__(self)

class EditableListCtrlGUT(wx.ListCtrl,
listmix.TextEditMixin,listmix.CheckListCtrlMixin):

 def __init__(self, parent, ID=wx.ID_ANY, pos=wx.DefaultPosition,

size=wx.DefaultSize, style=0):

     wx.ListCtrl.__init__(self, parent, ID, pos, size, style)

     listmix.TextEditMixin.__init__(self)

     listmix.CheckListCtrlMixin.__init__(self)

class MyPanel(wx.Panel):

 def __init__(self, parent):

     wx.Panel.__init__(self, parent)



     '''

     #no workie     inserted mod

     self.Panel = wx.Dialog(self.parent, style =

wx.ID_OK|wx.DEFAULT_DIALOG_STYLE)

     self.Panel.CheckModifyEvent, self.Panel.EVT_CHECKMODIFY =

wx.lib.newevent.NewEvent()

     self.ListCtrl = sssEditableListCtrl(self.Panel,

style=wx.LC_REPORT|wx.BORDER_SUNKEN)

     self.ListCtrl.InsertColumn(0, 'Col 1')

     self.ListCtrl.InsertColumn(1, 'Col 2')



     self.ListCtrl.Bind(wx.EVT_LIST_END_LABEL_EDIT, self.OnItemEdited)

     self.ListCtrl.Bind(wx.EVT_LIST_BEGIN_LABEL_EDIT,

self.OnStartingEditing)

     for i, itemForList in enumerate(self.itemsForList):

         self.ListCtrl.InsertStringItem(i, itemForList[0])

         self.ListCtrl.SetStringItem(i, 1, itemForList[1])



     # OTHER CODE FOR VISUALIZATION



 def OnStartingEditing(self, evt):

    if evt.m_col == 0:

        evt.Veto()

    else:

        evt.Skip()



 def OnItemEdited(self, evt):

     focusedRow = int(self.ListCtrl.GetFocusedItem())



     if evt.GetLabel() != "":

         self.ListCtrl.ToggleItem(focusedRow)

         # DO SOME OTHER STUFF

no workie

     '''









     rows = [(" ","Ford", "Capri", "1996", "Blue" ),

             (" ","Nissan", "370Z", "2010", "Green"),

             (" ","Porsche", "911", "2009", "Red")

             ]

     self.list_ctrl = sssEditableListCtrl(self, style=wx.LC_REPORT)





     self.list_ctrl.InsertColumn(0, "tagged")

     self.list_ctrl.InsertColumn(1, "Make")

     self.list_ctrl.InsertColumn(2, "Model")

     self.list_ctrl.InsertColumn(3, "Year")

     self.list_ctrl.InsertColumn(4, "Color")



     index = 0

     for row in rows:

         #self.list_ctrl.InsertStringItem(index, row[0])      #

depreceated

         self.list_ctrl.InsertItem(index, row[0])



         self.list_ctrl.SetItem(index, 1, row[1]) # remove String part

         self.list_ctrl.SetItem(index, 2, row[2])

         self.list_ctrl.SetItem(index, 3, row[3])

         self.list_ctrl.SetItem(index, 4, row[4])

         index += 1



     sizer = wx.BoxSizer(wx.VERTICAL)

     sizer.Add(self.list_ctrl, 0, wx.ALL|wx.EXPAND, 5)

     self.SetSizer(sizer)

class MyFrame(wx.Frame):

 def __init__(self):

     wx.Frame.__init__(self, None, wx.ID_ANY, "Editable List Control")

     panel = MyPanel(self)

     self.Show()

if name == “main”:

 app = wx.App(False)

 frame = MyFrame()

 app.MainLoop()