Recursive PersistenceManager

I am trying to add persistence to an app. However, I can’t seem to figure out how to make this work recursively.

Reading the docs for RegisterAndRestoreAll:

Recursively registers and restore the state of the input window and of all of its children.

… I thought, all children of an object would automatically be made persistent as well.

In my test example (see below), this doesn’t seem to work, though. Instead I get persistent settings of the main frame, while the two TextCtrls are not restored.

If I add pm.RegisterAndRestoreAll(tc1), I can get a persistent TextCtrl. However, this way I need to recurse through GetChildren() myself, which seems to contradict the docs.

What is the best way to get this working?

import os
import wx
from wx.lib.agw.persist import PersistenceManager


class PersistFrame(wx.Frame):

    def __init__(self):
        wx.Frame.__init__(self, None, title="A persistent window")
        self.Bind(wx.EVT_CLOSE, self.OnClose)

        tc1 = wx.TextCtrl(self, value="test1")
        tc2 = wx.TextCtrl(self, value="test2")

        box = wx.BoxSizer(wx.VERTICAL)
        box.Add(tc1)
        box.Add(tc2)

        self.SetSizerAndFit(box)

        self.SetName("Persist Frame") # Do not use the default name

        configFile = "persist.dat"
        configFile = os.path.join(os.getcwd(), configFile)
        self.pm = pm = PersistenceManager.Get()
        pm.SetPersistenceFile(configFile)
        pm.RegisterAndRestoreAll(self)


    def OnClose(self, event):
        self.pm.SaveAndUnregister()
        event.Skip()



if __name__ == "__main__":
    app = wx.App()
    pf = PersistFrame()
    pf.Show()
    app.MainLoop()

EDIT: I’d think the following would be a workaround. However, it’s an ugly one due to the broken names and the fact that adding a new widget anywhere would break it immediately. Also, I am not sure whether the order in GetChildren() or the order of generated IDs is actually guaranteed.

def RegisterAndRestoreAllRecursive(pm, obj, base="b"):
    obj.SetName(base)
    pm.RegisterAndRestoreAll(obj)
    children = obj.GetChildren()
    for i, child in enumerate(children):
        RegisterAndRestoreAllRecursive(pm, child, base=base+str(i))

or

def RegisterAndRestoreAllRecursive(pm, obj):
    ID = obj.GetId()
    obj.SetName(str(ID))
    pm.RegisterAndRestoreAll(obj)
    children = obj.GetChildren()
    for child in children:
        RegisterAndRestoreAllRecursive(pm, child)