nvdlg.py
5.14 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
#----------------------------------------------------------------------
# Name: wx.lib.nvdlg
# Purpose: Dialog for editing name/value pairs
#
# Author: Robin Dunn
#
# Created: 30-Nov-2009
# RCS-ID: $Id: $
# Copyright: (c) 2009 by Total Control Software
# Licence: wxWindows license
#----------------------------------------------------------------------
"""
A simple dialog that can prompt for values for any arbitrary set of name/value
pairs, where the fields are defined by a list of info passed to the
constructor. A dictionary of initial values can also be passed. Each item in
the fields list is a tuple of 3 items, which are:
* a string to be used for the attribute name for storing the value
* a string to be used for the label
* None, or a dictionary of kwargs to be passed to the wx.TextCtrl ctor
"""
import wx
MARGIN = 4
class SimpleNameValueDialog(wx.Dialog):
def __init__(self, parent, id=-1, title="", pos=wx.DefaultPosition,
size=wx.DefaultSize, style=wx.DEFAULT_DIALOG_STYLE,
fields=[], initialValues=None,
captionTitle="", captionDescr=""):
wx.Dialog.__init__(self, parent, id, title, pos, size, style)
self._fields = dict()
self.Sizer = wx.BoxSizer(wx.VERTICAL)
self._contentSizer = wx.FlexGridSizer(cols=2, hgap=MARGIN, vgap=MARGIN)
self._contentSizer.AddGrowableCol(1)
if captionTitle:
titleTxt = wx.StaticText(self, -1, captionTitle)
titleTxt.SetFont(wx.FFont(18, wx.SWISS, wx.FONTFLAG_BOLD))
self.Sizer.Add(titleTxt, 0, wx.ALL, MARGIN)
if captionDescr:
descTxt = wx.StaticText(self, -1, captionDescr)
self.Sizer.Add(descTxt, 0, wx.LEFT|wx.RIGHT|wx.BOTTOM, MARGIN)
if captionTitle or captionDescr:
self.Sizer.Add(wx.StaticLine(self), 0, wx.EXPAND|wx.TOP|wx.BOTTOM, MARGIN)
self.createFields(fields)
self.loadValues(initialValues)
self.Sizer.Add(self._contentSizer, 1, wx.EXPAND|wx.ALL, MARGIN)
self.Sizer.Add(wx.StaticLine(self), 0, wx.EXPAND|wx.TOP|wx.BOTTOM, MARGIN)
# TODO: add ability to specify which stock or custom buttons are used
btnSizer = wx.StdDialogButtonSizer()
btnSizer.AddButton(wx.Button(self, wx.ID_OK))
btnSizer.AddButton(wx.Button(self, wx.ID_CANCEL))
btnSizer.Realize()
self.Sizer.Add(btnSizer, 0, wx.EXPAND|wx.ALL, MARGIN)
self.FindWindowById(wx.ID_OK).SetDefault()
self.Fit()
def createFields(self, fields):
self.destroyFields()
for name, label, args in fields:
kwargs = dict(validator=_TransferValidator(name))
if args:
kwargs.update(args)
stxt = wx.StaticText(self, -1, label)
txt = wx.TextCtrl(self, **kwargs)
self._contentSizer.Add(stxt, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT)
self._contentSizer.Add(txt, 0, wx.EXPAND)
self.__dict__[name] = ""
self._fields[name] = (stxt, txt)
def destroyFields(self):
for name, widgets in self._fields.iteritems():
for w in widgets:
w.Destroy()
del self.__dict__[name]
def loadValues(self, values):
self.clearValues()
for name, value in values.iteritems():
if name in self._fields.keys():
setattr(self, name, value)
def clearValues(self):
for name in self._fields.keys():
setattr(self, name, "")
class _TransferValidator(wx.PyValidator):
"""
This validator is used to transfer values to/from the widgets and
attributes of the dialog.
"""
def __init__(self, name):
wx.PyValidator.__init__(self)
self.name = name
def Clone(self):
return _TransferValidator(self.name)
def Validate(self, win):
return True
def TransferFromWindow(self):
dlg = self.Window.Parent
value = dlg._fields[self.name][1].GetValue()
setattr(dlg, self.name, value)
return True
def TransferToWindow(self):
dlg = self.Window.Parent
value = getattr(dlg, self.name)
dlg._fields[self.name][1].SetValue(value)
return True
if __name__ == '__main__':
from wx.lib.mixins.inspection import InspectableApp
app = InspectableApp(redirect=False)
#app = wx.App(redirect=False)
fields = [ ('username', 'Login ID:', None),
('passwd', 'Password:', dict(size=(150,-1), style=wx.TE_PASSWORD)),
]
dlg = SimpleNameValueDialog(None, title="This is the title",
fields=fields,
initialValues=dict(username='rdunn'),
captionTitle="Login",
captionDescr="Enter your testing credentials")
if dlg.ShowModal() == wx.ID_OK:
print dlg.username, dlg.passwd
dlg.Destroy()
app.MainLoop()