pythonwxpython

How do I use wx.NewIdRef() correctly?


I'm on wxPython version 4.0.7.post2, and Python version 3.8.2. I've enabled warnings to catch the things I need to change in preparation for upgrading both Python and wxPython. One of the warnings I get is that wx.NewId() is deprecated. According to documentation, I should be using wx.NewIdRef(), which is supposed to be a drop-in replacement. Indeed, replacing all instances of wx.NewId() with wx.NewIdRef() works, but all the functions that take the id as a parameter trigger a new warning:

DeprecationWarning: an integer is required (got type WindowIDRef). Implicit conversion to integers using int is deprecated, and may be removed in a future version of Python.

Fine I say, let us use wx.NewIdRef().GetId() instead. i.e.:

my_id = wx.NewIdRef().GetId()
target.Bind(wx.EVT_MENU, self.foo, id=my_id)

This gives me the following error:

wx._core.wxAssertionError: C++ assertion "gs_autoIdsRefCount[winid] != ID_FREE" failed at ....\src\common\windowid.cpp(110) in `anonymous-namespace'::IncIdRefCount(): id should first be reserved

OK then, since it looks like passing wx.NewIdRef triggers an implicit __int__() conversion, what if I do this: my_id = wx.NewIdRef().__int__()?

Same error. Does wx.NewIdRef have a function to manually reserve it? Nope.

So what's the deal? How am I supposed to use wx.NewIdRef() correctly? And can I use wx.Window.NewControlId() instead?


Solution

  • It's a while now since I did the conversions to my wxPython projects but as I recall, most of the time, slotting in NewIdRef() worked.

    I ended up on the menus with this arrangement:

            e1 = wx.MenuItem(self.filem, wx.NewIdRef(), "&Encrypt/Decrypt")
            e1.SetBitmap(fs_images.getencryptBitmap())
            self.filem.Append(e1)
            self.Bind(wx.EVT_MENU, self.OnEncrypt, id=e1.GetId())
    

    Which has worked faultlessly.

    For areas where I need multiple Id's I've assigned them into a list and then taken them from that list i.e.

    self.recent_ids = [wx.NewIdRef() for i in range(self.MaxRecent+2)]
    

    Or, if I needed a fixed id:

    TIMESTAMPOFF = wx.NewIdRef()

    then:

    self.autom.AppendRadioItem(TIMESTAMP_OFF, 'Turn Off Automatic Timestamps')
    self.Bind(wx.EVT_MENU, self.OnAutoTimeStamp, id=TIMESTAMP_OFF)
    

    Hope it helps.