| 1 |
ninoborges |
8 |
from Tkinter import *
|
| 2 |
|
|
from string import *
|
| 3 |
|
|
from TKED import *
|
| 4 |
|
|
|
| 5 |
|
|
class EditRecord:
|
| 6 |
|
|
def __init__(self):
|
| 7 |
|
|
self.rec = []
|
| 8 |
|
|
|
| 9 |
|
|
def addvar(self, name, variable, type, default = None, set = None):
|
| 10 |
|
|
if type == CHECKBOX and default != 0 and default != 1:
|
| 11 |
|
|
print "Checkboxes need to define a default state (0 or 1)"
|
| 12 |
|
|
return
|
| 13 |
|
|
elif type == POPUP:
|
| 14 |
|
|
if default == None:
|
| 15 |
|
|
print "Popups need to define a default menu item (by number or name)"
|
| 16 |
|
|
return
|
| 17 |
|
|
elif set == None:
|
| 18 |
|
|
print "Popups need to define a set of items"
|
| 19 |
|
|
return
|
| 20 |
|
|
elif type == LISTBOX and default == None:
|
| 21 |
|
|
print "Listboxes need to define a default menu item (by number or name)"
|
| 22 |
|
|
return
|
| 23 |
|
|
if type == TEXTENTRY or type == CHECKBOX:
|
| 24 |
|
|
r = (type, name, variable, default)
|
| 25 |
|
|
self.rec.append(r)
|
| 26 |
|
|
elif type == POPUP:
|
| 27 |
|
|
r = (type, name, variable, default, set)
|
| 28 |
|
|
self.rec.append(r)
|
| 29 |
|
|
|
| 30 |
|
|
|
| 31 |
|
|
class Editor(Toplevel):
|
| 32 |
|
|
def __init__(self, objectname, creator, object = None, master = None):
|
| 33 |
|
|
Toplevel.__init__(self, master)
|
| 34 |
|
|
if object == None:
|
| 35 |
|
|
self.creating = 1
|
| 36 |
|
|
self.object = creator()
|
| 37 |
|
|
else:
|
| 38 |
|
|
self.creating = 0
|
| 39 |
|
|
self.object = object
|
| 40 |
|
|
self.objectname = objectname
|
| 41 |
|
|
self.editrec = EditRecord()
|
| 42 |
|
|
for var in self.object.vars:
|
| 43 |
|
|
vlabel, vname, vtype, vdefault = var
|
| 44 |
|
|
if self.creating == 0:
|
| 45 |
|
|
vdefault = getattr(object, vname)
|
| 46 |
|
|
self.editrec.addvar(vlabel, vname, vtype, vdefault)
|
| 47 |
|
|
self.createwidgets()
|
| 48 |
|
|
|
| 49 |
|
|
|
| 50 |
|
|
def addfield(self, fieldname, variable, defaultvalue = None):
|
| 51 |
|
|
self.vars.append((fieldname, variable, defaultvalue))
|
| 52 |
|
|
|
| 53 |
|
|
def createwidgets(self):
|
| 54 |
|
|
self.title = Label(self, text= self.objectname + ' Editor')
|
| 55 |
|
|
self.title.pack()
|
| 56 |
|
|
self.e = []
|
| 57 |
|
|
self.v = []
|
| 58 |
|
|
self.entries = Frame(self)
|
| 59 |
|
|
self.left = Frame(self.entries)
|
| 60 |
|
|
self.left.pack(side = LEFT, fill = BOTH)
|
| 61 |
|
|
self.right = Frame(self.entries)
|
| 62 |
|
|
self.right.pack(side = LEFT, fill = BOTH)
|
| 63 |
|
|
for i in range(len(self.editrec.rec)):
|
| 64 |
|
|
r = self.editrec.rec[i]
|
| 65 |
|
|
if len(r) == 5: ftype, fname, fvar, fdef, fset = r
|
| 66 |
|
|
elif len(r) == 4: ftype, fname, fvar, fdef = r
|
| 67 |
|
|
else: return
|
| 68 |
|
|
|
| 69 |
|
|
fl = Frame(self.left)
|
| 70 |
|
|
fl.pack( expand = 1, fill = BOTH)
|
| 71 |
|
|
fe = Frame(self.right)
|
| 72 |
|
|
fe.pack( expand = 1, fill = BOTH)
|
| 73 |
|
|
if ftype == TEXTENTRY:
|
| 74 |
|
|
v = StringVar()
|
| 75 |
|
|
if fdef:
|
| 76 |
|
|
v.set(fdef)
|
| 77 |
|
|
e = Entry(fe, borderwidth = 1, textvariable = v)
|
| 78 |
|
|
e.pack( side = LEFT, anchor = CENTER)
|
| 79 |
|
|
l = Label(fl, text = fname)
|
| 80 |
|
|
l.pack( expand = 1, anchor = E)
|
| 81 |
|
|
elif ftype == CHECKBOX:
|
| 82 |
|
|
v = BooleanVar()
|
| 83 |
|
|
l = Label( fl, text = fname)
|
| 84 |
|
|
l.pack( anchor = E )
|
| 85 |
|
|
e = Checkbutton( fe, variable = v, borderwidth = 1)
|
| 86 |
|
|
e.pack( anchor = E )
|
| 87 |
|
|
if fdef == 1:
|
| 88 |
|
|
e.select()
|
| 89 |
|
|
else:
|
| 90 |
|
|
e.deselect()
|
| 91 |
|
|
|
| 92 |
|
|
e.pack()
|
| 93 |
|
|
l.pack()
|
| 94 |
|
|
self.e.append(e)
|
| 95 |
|
|
self.v.append(v)
|
| 96 |
|
|
if i == 0:
|
| 97 |
|
|
e.focus()
|
| 98 |
|
|
|
| 99 |
|
|
self.entries.pack()
|
| 100 |
|
|
|
| 101 |
|
|
self.buttonbar = Frame(self)
|
| 102 |
|
|
self.buttonbar.ok = Button(self.buttonbar, relief = RIDGE, borderwidth = 3,
|
| 103 |
|
|
text = 'OK', command = self.ok)
|
| 104 |
|
|
self.buttonbar.cancel = Button(self.buttonbar, relief = GROOVE, text = 'Cancel',
|
| 105 |
|
|
command = self.cancel)
|
| 106 |
|
|
self.buttonbar.ok.pack(side = LEFT, fill = X, expand = 1)
|
| 107 |
|
|
self.buttonbar.cancel.pack( side = RIGHT, fill = X, expand = 1)
|
| 108 |
|
|
self.buttonbar.pack( side = BOTTOM, fill = X)
|
| 109 |
|
|
def ok(self):
|
| 110 |
|
|
for i in range(len(self.editrec.rec)):
|
| 111 |
|
|
r = self.editrec.rec[i]
|
| 112 |
|
|
if len(r) == 5: ftype, fname, fvar, fdef, fset = r
|
| 113 |
|
|
elif len(r) == 4: ftype, fname, fvar, fdef = r
|
| 114 |
|
|
if ftype == TEXTENTRY:
|
| 115 |
|
|
setattr(self.object, fvar, self.e[i].get())
|
| 116 |
|
|
elif ftype == CHECKBOX:
|
| 117 |
|
|
setattr(self.object, fvar, self.v[i].get() )
|
| 118 |
|
|
if (self.creating == 1):
|
| 119 |
|
|
self.master.addobject(self.object)
|
| 120 |
|
|
self.master.update()
|
| 121 |
|
|
self.destroy()
|
| 122 |
|
|
|
| 123 |
|
|
def cancel(self):
|
| 124 |
|
|
self.destroy()
|
| 125 |
|
|
|
| 126 |
|
|
|
| 127 |
|
|
|
| 128 |
|
|
class EditableObject:
|
| 129 |
|
|
def addvar(self, tuple):
|
| 130 |
|
|
self.vars.append(tuple)
|
| 131 |
|
|
vlabel, vname, vtype, vdefault = tuple
|
| 132 |
|
|
setattr(self, vname, vdefault)
|
| 133 |
|
|
|
| 134 |
|
|
def __init__(self):
|
| 135 |
|
|
self.vars = []
|
| 136 |
|
|
for tuple in self.varlist:
|
| 137 |
|
|
self.addvar(tuple)
|
| 138 |
|
|
|
| 139 |
|
|
|
| 140 |
|
|
if __name__ == '__main__':
|
| 141 |
|
|
from Tkinter import *
|
| 142 |
|
|
from string import *
|
| 143 |
|
|
from TKED import *
|
| 144 |
|
|
from filemaker import *
|
| 145 |
|
|
|
| 146 |
|
|
class Contact(EditableObject):
|
| 147 |
|
|
def __init__(self):
|
| 148 |
|
|
# this specifies the data format for records, and the variable names
|
| 149 |
|
|
self.varlist = (('First Name', 'first', TEXTENTRY, None), \
|
| 150 |
|
|
('Last Name', 'last', TEXTENTRY, None), \
|
| 151 |
|
|
('Phone #1', 'phone1', TEXTENTRY, None), \
|
| 152 |
|
|
('Time to call', 'times1', TEXTENTRY, None), \
|
| 153 |
|
|
('Phone #2', 'phone2', TEXTENTRY, None), \
|
| 154 |
|
|
('Time to call', 'times2', TEXTENTRY, None), \
|
| 155 |
|
|
('Nice person', 'nice', CHECKBOX, 1))
|
| 156 |
|
|
EditableObject.__init__(self)
|
| 157 |
|
|
|
| 158 |
|
|
# Subclass of Editor specifies the objects to be edited and the object's name
|
| 159 |
|
|
class ContactEditor(Editor):
|
| 160 |
|
|
def __init__(self, master, c):
|
| 161 |
|
|
Editor.__init__(self, 'Contact', Contact, c, master)
|
| 162 |
|
|
|
| 163 |
|
|
# Filemaker needs to know how to create the short 'label' which shows up in the list
|
| 164 |
|
|
def makelabel(s):
|
| 165 |
|
|
name = ' ' + s.first + ' ' + s.last
|
| 166 |
|
|
return name
|
| 167 |
|
|
|
| 168 |
|
|
t = FileMaker(ContactEditor, 'Contact', makelabel)
|
| 169 |
|
|
t.master.maxsize(300,300)
|
| 170 |
|
|
t.master.title('Contact Editor')
|
| 171 |
|
|
t.mainloop()
|
| 172 |
|
|
|