Search code examples
pythonwxpythonintegerobjectlistview

ObjectListView does not display zero


I'm using ObjectListView 1.2 (Python) and is quite confused by the weird behaviour. I have an object that has a double field. OLV will display the value if it is non-zero (whether it is int or double), but whenever the value is zero it just doesn't display anything for that object in that column.

SSCCE:

# -*- coding: utf-8 -*-
#!/usr/bin/env python

import wx

from ObjectListView import ObjectListView, ColumnDefn

class MyObj:
    def __init__(self, name, id):
        self.name = name
        self.id = id

    @staticmethod
    def getObjects():
        objList = []
        for i in range(0,5):
            objList.append(MyObj("item" + str(i), i))
        return objList

class MyFrame(wx.Frame):
    def __init__(self, *args, **kwds):
        wx.Frame.__init__(self, *args, **kwds)
        self.Init()

    def Init(self):
        self.InitModel()
        self.InitWidgets()
        self.InitObjectListView()

    def InitModel(self):
        self.songs = MyObj.getObjects()

    def InitWidgets(self):
        panel = wx.Panel(self, -1)
        sizer_1 = wx.BoxSizer(wx.VERTICAL)
        sizer_1.Add(panel, 1, wx.ALL|wx.EXPAND)
        self.SetSizer(sizer_1)

        self.myOlv = ObjectListView(panel, -1, style=wx.LC_REPORT|wx.SUNKEN_BORDER)
        sizer_2 = wx.BoxSizer(wx.VERTICAL)
        sizer_2.Add(self.myOlv, 1, wx.ALL|wx.EXPAND, 4)
        panel.SetSizer(sizer_2)

        self.Layout()

    def InitObjectListView(self):
        self.myOlv.SetColumns([
            ColumnDefn("Title", "left", 120, "name"),
            ColumnDefn("ID", "left", 120, "id")
        ])
        self.myOlv.SetObjects(self.songs)

if __name__ == '__main__':
    app = wx.PySimpleApp(1)
    wx.InitAllImageHandlers()
    frame_1 = MyFrame(None, -1, "ObjectListView Simple Example1")
    app.SetTopWindow(frame_1)
    frame_1.Show()
    app.MainLoop()

Solution

  • This appears to be a bug in ObjectListView. Whenever you set up a column with no stringConverter, it will ignore all "falsey" values (including zero). A comment in the code indicates that it is supposed to be ignoring None, but it catches all other false values as well.

    I would normally suggest reporting this bug upstream, but given that the project doesn't seem to have been updated in almost four years, I'm not sure that would be very productive.

    Instead, you can fix this by editing your copy of ObjectListView.py. The relevant method is in the ColumnDefn class:

    def _StringToValue(self, value, converter):
        """
        Convert the given value to a string, using the given converter
        """
        try:
            return converter(value)
        except TypeError:
            pass
    
        if converter and isinstance(value, (datetime.datetime, datetime.date, datetime.time)):
            return value.strftime(self.stringConverter)
    
        # By default, None is changed to an empty string.
        if not converter and not value:                # THE ERROR IS HERE!!!!
            return ""
    
        fmt = converter or "%s"
        try:
            return fmt % value
        except UnicodeError:
            return unicode(fmt) % value
    

    The fix is to change the line indicated to:

    if not converter and value is None: