__init__.py
7.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
"""
Introduction
============
Persistent objects are simply the objects which automatically save their state
when they are destroyed and restore it when they are recreated, even during
another program invocation.
.. _persistent-overview:
Persistent Object Overview
==========================
Most often, persistent objects are, in fact, persistent windows as it is especially
convenient to automatically restore the UI state when the program is restarted but
an object of any class can be made persistent. Moreover, persistence is implemented
in a non-intrusive way so that the original object class doesn't need to be modified
at all in order to add support for saving and restoring its properties.
The persistence framework involves:
* **PersistenceManager** which all persistent objects register themselves with. This class
handles actual saving and restoring of persistent data as well as various global
aspects of persistence, e.g. it can be used to disable restoring the saved data;
* **PersistentObject** is the base class for all persistent objects or, rather, adaptors
for the persistent objects as this class main purpose is to provide the bridge between
the original class -- which has no special persistence support -- and PersistenceManager;
* **PersistentHandlers** which handle different kind of saving/restoring actions depending
on the widget kind.
Using Persistent Windows
========================
wxPython has built-in support for a (constantly growing) number of controls. Currently the
following classes are supported:
* wx.TopLevelWindow (and hence wx.Frame and wx.Dialog, together with their own AUI perspectives);
* wx.MenuBar, FlatMenuBar;
* AuiToolBar;
* wx.Notebook, wx.Toolbook, wx.Treebook, wx.Choicebook, wx.aui.AuiNotebook,
AuiNotebook (together with its own AUI perspective),
FlatNotebook, LabelBook,
FlatImageBook;
* wx.CheckBox;
* wx.ListBox, wx.VListBox, wx.HtmlListBox, wx.SimpleHtmlListBox, wx.gizmos.EditableListBox;
* wx.ListCtrl, wx.ListView, UltimateListCtrl;
* wx.CheckListBox;
* wx.Choice, wx.ComboBox, wx.combo.OwnerDrawnComboBox;
* wx.RadioBox;
* wx.RadioButton;
* wx.ScrolledWindow, wx.lib.scrolledpanel.ScrolledPanel;
* wx.Slider, KnobCtrl;
* wx.SpinButton, wx.SpinCtrl, FloatSpin;
* wx.SplitterWindow;
* wx.TextCtrl, wx.SearchCtrl, wx.lib.expando.ExpandoTextCtrl, wx.lib.masked.Ctrl;
* wx.ToggleButton, wx.lib.buttons.GenToggleButton, wx.lib.buttons.GenBitmapToggleButton,
wx.lib.buttons.GenBitmapTextToggleButton, SToggleButton,
SBitmapToggleButton, SBitmapTextToggleButton;
* wx.TreeCtrl, wx.GenericDirCtrl, CustomTreeCtrl;
* wx.gizmos.TreeListCtrl, HyperTreeList;
* wx.lib.calendar.CalendarCtrl;
* wx.CollapsiblePane, PyCollapsiblePane;
* wx.DatePickerCtrl, wx.GenericDatePickerCtrl;
* wx.media.MediaCtrl;
* wx.ColourPickerCtrl, wx.lib.colourselect.ColourSelect;
* wx.FilePickerCtrl, wx.DirPickerCtrl;
* wx.FontPickerCtrl;
* wx.FileHistory;
* wx.DirDialog, wx.FileDialog;
* wx.FindReplaceDialog;
* wx.FontDialog;
* wx.ColourDialog, CubeColourDialog;
* FoldPanelBar;
* wx.SingleChoiceDialog, wx.MultiChoiceDialog;
* wx.TextEntryDialog, wx.PasswordEntryDialog.
To automatically save and restore the properties of the windows of classes listed
above you need to:
* Set a unique name for the window using `SetName()`: this step is important as the
name is used in the configuration file and so must be unique among all windows of
the same class;
* Call `PersistenceManager.Register(window)` at any moment after creating the window
and then `PersistenceManager.Restore(window)` when the settings may be restored
(which can't be always done immediately, e.g. often the window needs to be populated
first). If settings can be restored immediately after the window creation, as is often
the case for wx.TopLevelWindow, for example, then `PersistenceManager.RegisterAndRestore(window)`
can be used to do both at once.
* If you want the settings for the window to be saved when your main frame is destroyed (or your app closes), simply call
`PersistenceManager.SaveAndUnregister(window)` with no arguments.
Usage
=====
Example of using a notebook control which automatically remembers the last open page::
import wx, os
import wx.lib.agw.persist as PM
class MyFrame(wx.Frame):
def __init__(self, parent):
wx.Frame.__init__(self, parent, -1, "Persistent Controls Demo")
self.book = wx.Notebook(self, wx.ID_ANY)
# Very important step!!
self.book.SetName("MyBook") # Do not use the default name!!
self.book.AddPage(wx.Panel(self.book), "Hello")
self.book.AddPage(wx.Panel(self.book), "World")
self.Bind(wx.EVT_CLOSE, self.OnClose)
self._persistMgr = PM.PersistenceManager.Get()
_configFile = os.path.join(os.getcwd(), self.book.GetName())
self._persistMgr.SetPersistenceFile(_configFile)
if not self._persistMgr.RegisterAndRestoreAll(self.book):
# Nothing was restored, so choose the default page ourselves
self.book.SetSelection(0)
def OnClose(self, event):
self._persistMgr.SaveAndUnregister(self.book)
event.Skip()
# our normal wxApp-derived class, as usual
app = wx.App(0)
frame = MyFrame(None)
app.SetTopWindow(frame)
frame.Show()
app.MainLoop()
.. _persistent-windows:
Defining Custom Persistent Windows
==================================
User-defined classes can be easily integrated with PersistenceManager. To add support
for your custom class MyWidget you just need to:
* Define a MyWidgetHandler class inheriting from `AbstractHandler`;
* Implement its `GetKind()` method returning a unique string identifying all MyWidget
objects, typically something like "widget";
* Implement its `Save()` and `Restore()` methods to actually save and restore the widget
settings using `PersistentObject.SaveValue()` and `PersistentObject.RestoreValue()` methods.
If you want to add persistence support for a class not deriving from wx.Window, you need
to derive MyPersistentWidget directly from PersistentObject and so implement its
`PersistentObject.GetName()` method too. Additionally, you must ensure that
`PersistenceManager.SaveAndUnregister()` is called when your object is destroyed as this
can be only done automatically for windows.
TODOs
=====
* Find a way to handle :class:`ToolBar` UI settings as it has been done for :class:`~lib.agw.aui.auibar.AuiToolBar`:
current :class:`ToolBar` doesn't seem to have easy access to the underlying toolbar tools;
* Implement handler(s) for :class:`grid.Grid` for row/columns sizes (possibly adding another style
to `PersistenceManager` as :class:`grid.Grid` sets up arrays to store individual row and column
sizes when non-default sizes are used. The memory requirements for this could become prohibitive
if the grid is very large);
* Find a way to properly save and restore dialog data (:class:`ColourDialog`, :class:`FontDialog` etc...);
* Add handlers for the remaining widgets not yet wrapped (mostly in :mod:`lib`).
License And Version
===================
`PersistentObjects` library is distributed under the wxPython license.
Latest revision: Andrea Gavana @ 27 Mar 2013, 21.00 GMT
Version 0.4.
"""
__author__ = "Andrea Gavana <andrea.gavana@gmail.com>"
__date__ = "16 November 2009"
from persist_constants import *
from persistencemanager import *
from persist_handlers import *