wx.ListCtrl refresh - segmentation fault

Hi, guys

I’m new to both Python and to wxPython especially, so don’t judge too strongly.

Anyway, I’m trying to get used to Python GUI stuff and have trouble with refreshing ListCtrl (I’ve not used ObjectListView yet, if you suggest I may try. I tried to start simple).

I need to refill the content of a ListCtrl in the app.
Currently I’m doing it in a [probably stupid] way like

   self.mailListControl.DeleteAllItems()
   for email in messages:
        listItemIndex = self.mailListControl.InsertItem(
                self.mailListControl.GetItemCount(),
                email.accountName)
        self.mailListControl.SetItem(listItemIndex, 1, email.sender)
# more column filling here
        self.mailListControl.SetItem(listItemIndex, 6, email.uidl)
        self.mailListControl.SetItemData(listItemIndex, email.accountId)

The main reason is for doing it this way was I’m not familiar w/a better way and thought it should work fine. Mostly because every time the list needs to be refreshed it may contain different data and also different number of rows (sometimes no rows at all).

The problem is the app simply hangs in the middle of the loop (and I have to kill the process completely) and sometimes it even crashes with segmentation fault/core dump.

I kind of half-confident about the location where it happens in the code because it always happens when I know the app is supposed to refresh the list and also debug prints stop (I removed them from the sample above) in the middle of the loop as well.

Do you know if it may be an issue with the control or I’m not supposed to update the contents of it this way?

Thanks.

Sorry, this might be helpful: how I declare the control in the initialization block:

self.mailListControl = wx.ListCtrl(messagesPanel, wx.ID_ANY, style= wx.LC_REPORT)
self.mailListControl.InsertColumn(0, 'Mailbox', wx.LIST_FORMAT_LEFT)
self.mailListControl.InsertColumn(1, 'From', wx.LIST_FORMAT_LEFT)
# more column definitions
self.mailListControl.InsertColumn(6, 'UIDL', wx.LIST_FORMAT_LEFT, width=0)

Well, if you suspect you hit a bug in wxPython (and rest assured, it can happen!), first of all you should run a very basic version of what are trying to do, just for sanity check. Say, for instance, this code:

import wx
from random import randint

class MainFrame(wx.Frame):
    def __init__(self, *a, **k):
        wx.Frame.__init__(self, *a, **k)
        p = wx.Panel(self)
        b = wx.Button(p, -1, 'refresh', pos=(10, 10))
        b.Bind(wx.EVT_BUTTON, self.refresh)
        self.lst = wx.ListCtrl(p, pos=(10, 50), style= wx.LC_REPORT)
        self.lst.InsertColumn(0, 'first')
        self.lst.InsertColumn(1, 'second')
        self.lst.InsertColumn(2, 'third')

    def refresh(self, e):
        self.lst.DeleteAllItems()
        for i in range(10):
            itemdata = randint(0, 100)
            idx = self.lst.InsertItem(10, str(itemdata))
            self.lst.SetItem(idx, 1, str(randint(0, 100)))
            self.lst.SetItem(idx, 2, str(randint(0, 100)))
            self.lst.SetItemData(idx, itemdata)

app = wx.App(False)
MainFrame(None).Show()
app.MainLoop()

Now, if this code doesn’t work for you, then you just hit a gigantic bug in wx.ListCtrl. Congratulations (well, sort of)! You should immediately file a bug on the issue tracker https://github.com/wxWidgets/Phoenix/issues

If this code works for you, then you should carefully inspect your own code instead, trying to figure out what you are doing different from the basic working example. Leave out all the unnecessary, unrelated code, maybe use some fake data to fill in your list, etc. When you hit the exact point where you get the error, then it will be one of the two: either it is a mistake on your side which you can easily fix, or you are doing everything right and you hit a bug in wxPython. If so, you should provide a short example (20 lines or so) that triggers the bug, and submit it to the bug tracker.

I c.
Okay, will do a shortened version and c if it fails or not.

Thanks for the tip.

I’m still working on the sample app but as a general comment, in addition to segmentation fault I also c (never mind line wrapping, i made it 2 help read the output)

/tmp/pip-install-aq7uwy1s/wxPython/ext/wxWidgets/src/common/object.cpp(339): 
  assert "m_count > 0" failed in DecRef(): 
     invalid ref data count

and also this

/tmp/pip-install-aq7uwy1s/wxPython/ext/wxWidgets/src/common/object.cpp(339): 
   assert "m_count > 0" failed in DecRef(): invalid ref data count
      corrupted double-linked list
Aborted (core dumped)

Not sure what this is caused by. May b that’s an indication of something i’m doing wrong in layout code.

Looks like I found the issue.
It’s about my multi-threaded app and async UI updates (via callbacks via callbacks).

I switched 2 using sending events instead of calling UI methods directly from the async thread and now it’s okay.

multi-threaded app

You know, I can’t shake the feeling that this detail could have been brought to our attention a little earlier.

sending events instead of calling UI methods

yes, that is probably for the better.

I apologize 4 the confusion.

That’s probably the usual culprit in any language (I’m coming from Java bkgnd). I should definitely have said that in the beginning. I totally forgot about GUI apps’ usual ‘main event loop’ (I mostly code stupid single-threaded web/service-oriented apps).

As soon as i recalled about ‘the loop’ i realized that event my naive thought about trying 2 do even async callbacks from UI 2 presenter (I’m currently using ‘model-view-presenter’ pattern) wouldn’t work, since presenter is a threaded class and the direct hard calls from presenter back 2 UI would conflict w/the main GUI loop anyway.

Old lesson recalled… Thanks 4 your help, anyway. It’s the sample u provided made me realize the diff between it and my actual app.