无法使用 wxPython PersistenceManager 保存持久性文件

Unable to save persistence file using wxPython PersistenceManager

我正在使用 wxpython 开发一个 GUI 应用程序,它有大约 110 个用户选择的参数。因为我希望用户能够将这些选项保存到项目文件中,所以我决定使用 wxPython 中包含的 PersistenceManager 模块。

只要我不尝试指定保存设置的文件名,即我使用默认值 (C:\users\username\AppData\programName\Persistence_Options),并且只让程序保存退出时的设置。

我想做的是允许用户选择一个文件来保存设置(因为他们可能有多个具有不同选项的项目)。但是,当我将 SetPersistenceFile 方法与用户指定的文件名一起使用时,没有文件被保存,也没有返回错误消息,即使它确实在执行下面给出的那些代码行。 (OnSave函数是程序主要window的一个方法。)

def OnSave(self, e):
    self.dirname = os.getcwd()
    if self.ProjectFile == '':
        dlg = wx.FileDialog(self, "Save project file", self.dirname, "", "Project configuration file (.prj)|*.prj", wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT)
        if dlg.ShowModal() == wx.ID_CANCEL:
            return
        else:
            self.ProjectFile = os.path.join(dlg.GetDirectory(), dlg.GetFilename())
            #print self.ProjectFile

    if self.ProjectFile != '':
        print "Made it to here (Save)..."
        #self.Register(self) # Also tried calling Register in __init__
        self._persistMgr = PM.PersistenceManager.Get()
        print self.ProjectFile # Gives correct filename
        self._persistMgr.SetPersistenceFile(self.ProjectFile)
        self._persistMgr.Save(self)
        print "Finished saving."

我试过使用本地 PersistenceManager 对象,而不是将其作为 class 成员,这没有任何区别。有趣的是,如果我在 window 的 __init__ 函数中声明 self.__persistMgr 对象并在那里使用带有硬编码文件名的 SetPersistenceFile 方法,它会写入文件,然而,这没有帮助,因为用户需要在运行时指定它。

有谁知道为什么文件没有保存,我该如何解决这个问题?

不确定为什么您的代码让您感到悲伤,下面的内容适用于 Linux,尽管这可能对您没有任何安慰。
它是从许多来源拼凑而成的,我自己没有遇到 PersistenceManager

#!/usr/bin/python
import wx , os
import wx.lib.agw.persist as PM

class persist(wx.Frame):
    def __init__(self, parent):
        wx.Frame.__init__(self, parent, -1, "A window that maintains size and position after restart")
        self.Bind(wx.EVT_CLOSE, self.OnClose)

        # Very important step!!
        if self.GetName() == "frame":
            self.SetName("My Persist Frame") # Do not use the default name!!

        dirname = os.getcwd()
        dlg = wx.FileDialog(self, "Project file", dirname, "", "Project configuration file (.prj)|*.prj|All files (*.*)|*.*", wx.FD_SAVE)
        if dlg.ShowModal() == wx.ID_CANCEL:
            _configFile = os.path.join(os.getcwd(), "persist-saved.prj")    # getname()
        else:
            _configFile = os.path.join(dlg.GetDirectory(), dlg.GetFilename())
        print _configFile
        self._persistMgr = PM.PersistenceManager.Get()
        self._persistMgr.SetPersistenceFile(_configFile)
        self._persistMgr.RegisterAndRestoreAll(self)
        self._persistMgr.Save(self)

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

if __name__ == '__main__':
    my_app = wx.App()
    p = persist(None)
    p.Show()
    my_app.MainLoop()

我的 .prj 文件中的结果:

[Persistence_Options]
[Persistence_Options/Window]
[Persistence_Options/Window/My\ Persist\ Frame]
x=('int', '9')
y=('int', '134')
w=('int', '319')
h=('int', '78')
Maximized=('bool', 'False')
Iconized=('bool', 'False')

请注意 name 的设置,这适用于您为持久性保存的内容。

编辑:关于您的评论 我认为您可能希望 PersistenceManager 目前无法应对。

wxWidgets has built-in support for a (constantly growing) number of controls. Currently the following classes are supported:

wxTopLevelWindow(以及 wxFrame 和 wxDialog) wxBookCtrlBase(即 wxNotebook、wxListbook、wxToolbook 和 wxChoicebook) wx树书 要自动保存和恢复上面列出的 class 的 windows 的属性,您需要:

使用 wxWindow::SetName() 为 window 设置一个唯一的名称:这一步很重要,因为该名称在配置文件中使用,因此在所有 windows 中必须是唯一的相同 class。 在创建 window 之后随时调用 wxPersistenceManager::Register() ,然后在可以恢复设置时调用 wxPersistenceManager::Restore() (这不能总是立即完成,例如通常 window 需要先填充)。如果在创建 window 之后可以立即恢复设置,例如 wxTopLevelWindow 通常就是这种情况,那么可以使用 wxPersistenceManager::RegisterAndRestore() 同时完成这两项工作。 如果您不想保存 window 的设置(例如,如果对话框被取消,对话框大小的更改通常不会保存),您需要手动调用 wxPersistenceManager::Unregister()。否则当控件本身被销毁时设置将被自动保存。
资料来源:http://www.ccp4.ac.uk/dist/checkout/wxPython-src-3.0.2.0/docs/doxygen/out/html/overview_persistence.html

当然我可能错得离谱,正如我已经承认的那样,我以前没有使用过它,也没有真正正确地调查过它。