wxPython 101 – wx.NewId() is Deprecated!

Deprecation warnings are handy ways for open-source maintainers to alert their users that some part of their package is no longer going to be supported. Good maintainers will provide migration guides that tell you what to do when you see a deprecation warning.

You don’t want to ignore a deprecation warning because it alerts you that a feature is disappearing. If you upgrade to the latest without mitigating the warnings, you will almost certainly have one or more broken applications to fix.

wxPython is not immune to deprecation warnings either. In this article, you will learn about what to do when see a DeprecationWarning about wx.NewId().

Ye Olde wx.NewId

If you would like to see the deprecation error, all you need is wxPython 4-4.2 or so and add a call to wx.NewId().

One of the most common places to use wx.NewId() is in a wx.Menu item. Here’s an example:

import wx


class MyFrame(wx.Frame):
    def __init__(self):
        super().__init__(parent=None, title="wx.Menu Tutorial")

        self.panel = wx.Panel(self, wx.ID_ANY)

        menu_bar = wx.MenuBar()
        file_menu = wx.Menu()
        exit_menu_item = file_menu.Append(wx.NewId(), "Exit", "Exit the application")
        menu_bar.Append(file_menu, "&File")
        self.Bind(wx.EVT_MENU, self.on_exit, exit_menu_item)
        self.SetMenuBar(menu_bar)

    def on_exit(self, event):
        self.Close()


# Run the program
if __name__ == "__main__":
    app = wx.App(False)
    frame = MyFrame().Show()
    app.MainLoop()

When you run this code, you will see the following text in your terminal or IDE’s stdout:

C:\code\bad_menu.py:12: DeprecationWarning: NewId() is deprecated
  exit_menu_item = file_menu.Append(wx.NewId(), "Exit", "Exit the application")

Let’s find out how to fix this problem in the next section!

Using wx.NewIdRef()

The fix for this particular deprecation warning from wxPython is to use wx.NewIdRef() instead of wx.NewId().

Swap out the new call like so:

import wx


class MyFrame(wx.Frame):
    def __init__(self):
        super().__init__(parent=None, title="wx.Menu Tutorial")

        self.panel = wx.Panel(self, wx.ID_ANY)

        menu_bar = wx.MenuBar()
        file_menu = wx.Menu()
        exit_menu_item = file_menu.Append(wx.NewIdRef(), "Exit", "Exit the application")
        menu_bar.Append(file_menu, "&File")
        self.Bind(wx.EVT_MENU, self.on_exit, exit_menu_item)
        self.SetMenuBar(menu_bar)

    def on_exit(self, event):
        self.Close()


# Run the program
if __name__ == "__main__":
    app = wx.App(False)
    frame = MyFrame().Show()
    app.MainLoop()

You will no longer receive a deprecation warning when you run this updated code!

Wrapping Up

Deprecation warnings are not a big deal. But if you plan to do a new release, then you should spend a little extra time taking care of them so they don’t bite you later on.

Have fun and happy coding!