无法使用 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
当然我可能错得离谱,正如我已经承认的那样,我以前没有使用过它,也没有真正正确地调查过它。
我正在使用 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
当然我可能错得离谱,正如我已经承认的那样,我以前没有使用过它,也没有真正正确地调查过它。