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

Python 2.7 无法使用wxPython PersistenceManager保存持久性文件,python-2.7,wxpython,Python 2.7,Wxpython,我正在使用wxpython开发一个GUI应用程序,它有大约110个用户选择的参数。因为我希望用户能够将这些选项保存到项目文件中,所以我决定使用wxPython附带的PersistenceManager模块 只要我不尝试指定保存设置的文件名,即使用默认值(C:\users\username\AppData\programName\persistence\u Options),只要让程序在退出时保存设置,持久性就可以了 我试图做的是允许用户选择一个文件来保存设置(因为他们可能有多个具有不同选项的项目

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

只要我不尝试指定保存设置的文件名,即使用默认值(
C:\users\username\AppData\programName\persistence\u Options
),只要让程序在退出时保存设置,持久性就可以了

我试图做的是允许用户选择一个文件来保存设置(因为他们可能有多个具有不同选项的项目)。但是,当我对用户指定的文件名使用
SetPersistenceFile
方法时,不会保存任何文件,也不会返回任何错误消息,即使它确实在执行下面给出的代码行。(保存功能是程序主窗口的一种方法。)

我尝试过使用本地PersistenceManager对象,而不是将其作为类成员,这没有什么区别。有趣的是,如果我在窗口的
\uuu init\uuu
函数中声明
self.\uu 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()
结果在my.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')
请注意,
名称的设置
对于要保存以进行持久化的任何内容都是如此

编辑:关于你的评论 我认为您可能希望的不仅仅是
PersistenceManager
目前能够处理的问题

wxWidgets内置了对(不断增长的)控件数量的支持。目前支持以下类:

wxTopLevelWindow(以及wxFrame和wxDialog) wxBookCtrlBase(即wxNotebook、wxListbook、wxToolbook和wxChoicebook) wxTreebook 要自动保存和恢复上面列出的类的窗口属性,您需要:

使用wxWindow::SetName()设置窗口的唯一名称:此步骤很重要,因为该名称在配置文件中使用,因此在同一类的所有窗口中必须是唯一的。 在创建窗口后的任何时候调用wxPersistenceManager::Register(),然后在可以恢复设置时调用wxPersistenceManager::Restore()(这不能总是立即完成,例如,通常需要先填充窗口)。如果可以在创建窗口后立即恢复设置,例如wxTopLevelWindow,则可以使用wxPersistenceManager::RegisterAndRestore()同时执行这两项操作。 如果不希望保存窗口的设置(例如,如果取消对话框,通常不会保存对对话框大小的更改),则需要手动调用wxPersistenceManager::Unregister()。否则,当控件本身被销毁时,设置将自动保存。
资料来源:


当然,我可能会大错特错,正如我已经承认的那样,我以前没有使用过它,也没有真正正确地研究过它。

不知道为什么你的代码会让你感到悲伤,下面的代码在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()
结果在my.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')
请注意,
名称的设置
对于要保存以进行持久化的任何内容都是如此

编辑:关于你的评论 我认为您可能希望的不仅仅是
PersistenceManager
目前能够处理的问题

wxWidgets内置了对(不断增长的)控件数量的支持。目前支持以下类:

wxTopLevelWindow(以及wxFrame和wxDialog) wxBookCtrlBase(即wxNotebook、wxListbook、wxToolbook和wxChoicebook) wxTreebook 要自动保存和恢复上面列出的类的窗口属性,您需要:

使用wxWindow::SetName()设置窗口的唯一名称:此步骤很重要,因为该名称在配置文件中使用,因此在同一类的所有窗口中必须是唯一的。 在创建窗口后的任何时候调用wxPersistenceManager::Register(),然后在可以恢复设置时调用wxPersistenceManager::Restore()(这不能总是立即完成,例如,通常需要先填充窗口)。如果可以在创建窗口后立即恢复设置,例如wxTopLevelWindow,则可以使用wxPersistenceManager::RegisterAndRestore()同时执行这两项操作。 如果不希望保存窗口的设置(例如,如果取消对话框,通常不会保存对对话框大小的更改),则需要手动调用wxPersistenceManager::Unregister()。否则,当控件本身被销毁时,设置将自动保存。
资料来源:


当然,我可能会大错特错,正如我已经承认的那样,我以前没有使用过它,也没有真正正确地研究过它。

感谢您的关注。这个例子很好,但是如果你把它放在一个单独的函数中(就像我正在尝试做的那样),它似乎只捕获框架属性,而不是名为controls的子控件。如果您将其保留在原来的位置,子控件将正确保存。添加了对我原始答案的引用谢谢您的查看。这个例子很好,但是如果