ANN: ObjectListView3 for wxPython

ObjectListView is a third-party wxPython widget that wraps the wx.ListCtrl. I have used it for over 10 years in quite a few different GUI applications because it works much nicer than wx.ListCtrl does. Unfortunately, ObjectListView was never integrated into wxPython core like some other amazing third-party packages were, and so it has become broken over the past couple of years such that you can’t use it with the latest version of Python / wxPython.

So, I decided to fork the project, as its defects were simple enough that I could resolve them quickly. The new version of ObjectListView is now called ObjectListView3.

You can get the new version of ObjectListview here:

Note that this version of ObjectListView works with Python 3.11+ and wxPython 4.2+. It may work with earlier versions as well.

Installation

If you’d like to install ObjectListView3, you can use Python’s pip to do so like this:

python -m pip install ObjectListView3

Now let’s see how an example of using ObjectListView!

Sample Usage

The following is an application that starts out by listing two books in an ObjectListView3 widget. When you press the “Update OLV” button, it will add three more books to the ObjectListView3 widget.

This demonstrates how to create the ObjectListview3 widget and update it after the application is running:

import wx
from ObjectListView3 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):
        super().__init__(parent=parent, id=wx.ID_ANY)
        self.products = [
            Book("wxPython in Action", "Robin Dunn", "1932394621", "Manning"),
            Book("Hello World", "Warren and Carter Sande", "1933988495", "Manning"),
        ]

        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 update button
        updateBtn = wx.Button(self, wx.ID_ANY, "Update OLV")
        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):
        """
        Update the ObjectListView
        """
        product_dict = [
            {
                "title": "Core Python Programming",
                "author": "Wesley Chun",
                "isbn": "0132269937",
                "mfg": "Prentice Hall",
            },
            {
                "title": "Python Programming for the Absolute Beginner",
                "author": "Michael Dawson",
                "isbn": "1598631128",
                "mfg": "Course Technology",
            },
            {
                "title": "Learning Python",
                "author": "Mark Lutz",
                "isbn": "0596513984",
                "mfg": "O'Reilly",
            },
        ]
        data = self.products + product_dict
        self.dataOlv.SetObjects(data)

    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 OLVDemoApp(wx.App):
    def __init__(self, redirect=False, filename=None):
        super().__init__(redirect, filename)

    def OnInit(self):
        # create frame here
        frame = MainFrame()
        frame.Show()
        return True


def main():
    """
    Run the demo
    """
    app = OLVDemoApp()
    app.MainLoop()


if __name__ == "__main__":
    main()

When you initially run this code, you will see the following application:

ObjectListView3 Demo App

When you press the “Update OLV” button, the application will update to look like the following:

Updated ObjectListView3 Demo app

Wrapping Up

The ObjectListView3 widget makes working with tabular data easy in wxPython. You also get nice editing, sorting and more from this widget via different mixins or styles. Give ObjectListView3 a try when you create your next wxPython GUI application.