简体   繁体   中英

Is there a cross-platform convention/location for storing desktop app settings?

As part of my first project of developing a desktop GUI app with Python, is there a standard or conventional location or means of storing application defaults? As an example, there may be resources such as icons or other images used by the application which shouldn't be stored in the source tree.

With user-specific config files it's straightforward to set the default config directory to '~/.app_config' and use os.path.expanduser() to generate an appropriate path on both Windows and Linux (ignoring the fact that recent versions of Windows store settings under "~/Application Data" or "~/Local Settings") That's fine for user-level configs, but I'm looking for language or toolkit conventions for resource storage in a professionally packaged application.

I'm currently using Jython, but this should be applicable to wxPython, other GUI toolkits, and CLI applications. I appreciate the flexibility I have but frankly, I want to put things in a "standard" location and I'm too lazy and not arrogant enough to just make up what "standard" is. :)

Update: The appdirs module seems to do exactly what I'm looking for. In retrospect, I found this question and this question which are essentially duplicates.

You should use wx.StandardPaths . There is a good example in the wxPython demo. I took that example and created a runnable version below:

import wx

#----------------------------------------------------------------------
class TestPanel(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent, -1)

        sizer = wx.FlexGridSizer(0, 3, 5, 5)
        sizer.AddGrowableCol(1)
        box = wx.BoxSizer(wx.VERTICAL)
        fs = self.GetFont().GetPointSize()
        bf = wx.Font(fs+4, wx.SWISS, wx.NORMAL, wx.BOLD)

        t = wx.StaticText(self, -1, "StandardPaths")
        t.SetFont(bf)
        box.Add(t, 0, wx.CENTER|wx.ALL, 4)
        box.Add(wx.StaticLine(self, -1), 0, wx.EXPAND)

        # get the global (singleton) instance of wx.StandardPaths
        sp = wx.StandardPaths.Get()

        # StandardPaths will use the value of wx.App().GetAppName()
        # for some of the stnadard path components.  Let's set it to
        # something that makes that obvious for the demo.  In your own
        # apps you'll set it in to something more meaningfull for your
        # app in your OnInit, (or just let it default.)
        wx.GetApp().SetAppName("AppName")

        self.help = {}

        # Loop through all of the getters in wx.StandardPaths and make
        # a set of items in the sizer for each.
        def makeitem(name, *args):
            func = getattr(sp, name)
            sizer.Add(wx.StaticText(self, -1, "%s%s:" %(name, repr(args))),
                      0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL)
            sizer.Add(wx.TextCtrl(self, -1, func(*args),
                                  size=(275,-1), style=wx.TE_READONLY),
                      0, wx.EXPAND|wx.ALIGN_CENTER_VERTICAL)

            btn = wx.Button(self, wx.ID_HELP)
            sizer.Add(btn)
            self.help[btn] = func.__doc__

        for x in ['GetConfigDir',
                  'GetUserConfigDir',
                  'GetDataDir',
                  'GetLocalDataDir',
                  'GetUserDataDir',
                  'GetUserLocalDataDir',
                  'GetDocumentsDir',
                  'GetPluginsDir',
                  'GetInstallPrefix',
                  'GetResourcesDir',
                  'GetTempDir',
                  'GetExecutablePath',
                  ]:
            makeitem(x)

        # this one needs parameters
        makeitem('GetLocalizedResourcesDir', 'en',
                 wx.StandardPaths.ResourceCat_Messages )

        self.Bind(wx.EVT_BUTTON, self.OnShowDoc, id=wx.ID_HELP)

        box.Add(sizer, 0, wx.CENTER|wx.EXPAND|wx.ALL, 20)
        self.SetSizer(box)

    def OnShowDoc(self, evt):
        doc = self.help[evt.GetEventObject()]

        # trim the whitespace from each line
        lines = []
        for line in doc.split('\n'):
            lines.append(line.strip())
        doc = '\n'.join(lines)
        wx.TipWindow(self, doc, 500)    

#----------------------------------------------------------------------
class MyFrame(wx.Frame):
    """"""

    def __init__(self):
        wx.Frame.__init__(self, None, title="Standard Paths",
                          size=(800,600))
        panel = TestPanel(self)
        self.Show()

if __name__ == "__main__":
    app = wx.App(False)
    frame = MyFrame()
    app.MainLoop()

For more information, I recommend reading the documentation:

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM