tVector - надстройка над диспетчером pack() позволяющая располагать виджеты в виде "векторов" - строк или столбцов. Черезвычайно удобная вещь, оставляющая в прошлом мороку с расстановкой элементов на сложных формах. Несколько модифицирована чтобы можно было создавать список виджетов в цикле и передавать параметры упаковщика EXPAND и FILL для каждого конкретного виджета.
Пример встроен в сам скрипт.
1 """
2 Convenience layer for Tkinter.
3
4 Allows window specifications to be created with far less,
5 and much more readable code, than doing it by hand.
6
7 Contains classes Row and Col, for building rows and columns
8 of widgets, and building these into a live frame.
9 """
10
11 import Tkinter
12 from Tkinter import *
13
14
15 class Vector(Frame):
16 """
17 Tkinter vectors.
18
19 A helper class for the easy creation and use of Tkinter layouts.
20
21 (don't use this class directly - you should use the derived 'Row'
22 and 'tVer' classes instead)
23
24 For a working example, see this module's docstring
25 """
26 def __init__(self, direction, *widgets, **kwds):
27 """
28 Creates an array of widgets (or widget vectors)
29
30 Best not to use this class directly - use one of the derived
31 classes 'HOR' or 'VER' instead.
32 """
33 if direction == 'right':
34 self.packside = LEFT
35 else:
36 self.packside = TOP
37
38 if kwds.has_key('widget_list'):
39 self.widlist = kwds['widget_list']
40 del kwds['widget_list']
41 else:
42 self.widlist = widgets
43
44 self.kwds = kwds
45
46 self.wids = {} # populate this during build
47
48 def build(self, parent, **kw):
49 """
50 Recursively descend through the widgets list, and construct/pack
51 the window structure
52 """
53 self.wids = {}
54
55 if kw.has_key('fill'):
56 fill = kw['fill']
57 del kw['fill']
58 else:
59 fill = BOTH
60
61 if kw.has_key('expand'):
62 expand = kw['expand']
63 del kw['expand']
64 else:
65 expand = YES
66
67 # construct Frame for this vector
68 #Frame.__init__(self, parent, self.kwds)
69 Frame.__init__(self, parent, self.kwds)
70 self.pack(side=self.packside, fill=fill, expand=expand)
71
72 for wid in self.widlist:
73 if isinstance(wid, Vector):
74 wname = None
75 wref = wid.build(self)
76 self.wids.update(wid.wids)
77 else:
78 wcls = wid['class']
79 wname = wid['name']
80 wargs = wid['args']
81 wkwds = wid['kwds']
82
83 if wkwds.has_key('fill'):
84 fill = wkwds['fill']
85 del wkwds['fill']
86 else:
87 fill = BOTH
88
89 if wkwds.has_key('expand'):
90 expand = wkwds['expand']
91 del wkwds['expand']
92 else:
93 expand = YES
94
95 wref = wcls(self, *wargs, **wkwds)
96
97 wref.pack(side=self.packside, fill=fill, expand=expand)
98
99 if wname:
100 self.wids[wname] = wref
101
102 return self
103
104 def control(self, widname=None, **kwds):
105 """
106 Versatile method.
107
108 Looks up component widgets by name. If any keywords are supplied,
109 the widget's config() method will be called with these keywords.
110
111 3 ways of using:
112 - with no arguments at all, returns a list of widget names
113 - with just a widget name argument, returns a ref to that widget
114 - with widget name and some keywords, calls config() on that widget
115 and passes the given keywords.
116
117 Examples:
118
119 # get a list of widgets for vector 'mywin'
120 widgets = mywin.wid()
121
122 # get a handle to the widget 'label1'
123 mylabel = mywin.wid('label1')
124
125 # change the text of 'label1'
126 mywin.wid('label1', text="Different text for label1")
127
128 """
129 if not widname:
130 return self.wids.keys()
131 else:
132 try:
133 wid = self.wids[widname]
134 if len(kwds) > 0:
135 wid.config(**kwds)
136 else:
137 return self.wids[widname]
138 except:
139 raise AttributeError
140
141 class Row(Vector):
142 """
143 Creates a horizontal vector of widgets.
144
145 For usage info, refer to Vector docstring
146 """
147 def __init__(self, *widgets, **kwds):
148 """
149 Constructor for Row - a horizontal vector of widgets
150
151 Arguments:
152 - widget1
153 - widget2
154 - ...
155
156 Each widget should be either be something returned from W,
157 or a Row or Col instance.
158
159 For an example, refer to docstring for Vector class
160 """
161 Vector.__init__(self, 'right', *widgets, **kwds)
162
163 class Col(Vector):
164 """
165 Creates a vertical column of widgets.
166
167 For usage info, refer to Vector docstring
168 """
169 def __init__(self, *widgets, **kwds):
170 """
171 Constructor for Row - a vertical vector of widgets
172
173 Arguments:
174 - widget1
175 - widget2
176 - ...
177
178 Each widget should be either be something returned from W,
179 or a Row or Col instance.
180
181 For an example, refer to docstring for Vector class
182 """
183 Vector.__init__(self, 'down', *widgets, **kwds)
184
185
186 def W(widclass, widname, *args, **kwds):
187 """
188 Helper function for Row and Col classes.
189
190 Generates a widget entry and translates it into a dict that can be
191 fed straight to the Row and Col constructors.
192
193 Refer to the Vector docstring for more info.
194
195 Arguments:
196 - widclass - a widget class object that behaves like normal tk widgets
197 - widname - name to give to this widget (accessible later via
198 Row.wid and Col.wid methods)
199 - extra arguments are passed to the widget constructor
200 Keywords:
201 - anything you give gets passed straight to widget constructor
202
203 Example:
204
205 W(Tkinter.Button, 'mybutton1', text="Button 1")
206 """
207
208 return {'name':widname,
209 'class':widclass,
210 'args':args,
211 'kwds':kwds}
212
213 class mywin:
214 def __init__(self, parent):
215 self.layout = Col(W(Label, 'L1',
216 text="Window Heading",
217 font="helvetica 16 bold"),
218 W(Checkbutton, 'Chk1',
219 text="A checkbutton"),
220 Row(W(Button, 'but1',
221 text="Button 1",
222 command=self.on_button1),
223 W(Button, 'but2',
224 text="Button 2",
225 command=self.on_button2),
226 W(Button, 'but3',
227 text="Button 3",
228 command=self.on_button3)),
229 Row(W(Entry, 'fld1',
230 text="field 1"),
231 W(Entry, 'fld2',
232 text="field 2")))
233 self.layout.build(parent)
234
235 def on_button1(self):
236 print "clicked button1"
237 self.layout.control('but1', text="New Button1 label")
238
239 def on_button2(self):
240 print "clicked button2"
241 self.layout.control('but1', text='Button 1')
242
243 def on_button3(self):
244 print "clicked button3"
245
246 def mainloop(self):
247 self.layout.mainloop()
248
249 if __name__ == '__main__':
250 root = Tk()
251 app = mywin(root)
252 app.mainloop()
Пример 2:
1 import Tkinter as tk
2 from vector import *
3
4 root = tk.Tk()
5 root.title("Пример")
6 layout = [W(tk.Label,'title',text='Заголовок',font=("Monotype Corsiva", 17, "bold italic")),
7 Row(
8 W(tk.Label,'label_1',text=' A: '),
9 W(tk.Entry,'entry_1',width=5,expand=tk.NO,fill=tk.NONE),
10 W(tk.Label,'label_2',text=' B: '),
11 W(tk.Entry,'entry_2',width=5,expand=tk.NO,fill=tk.NONE),
12 W(tk.Label,'label_3',text=' C: '),
13 W(tk.Entry,'entry_3',width=5,expand=tk.NO,fill=tk.NONE),
14 W(tk.Label,'label_4',text=' D: '),
15 W(tk.Entry,'entry_4',width=5,expand=tk.NO,fill=tk.NONE)),
16 Row(
17 W(tk.Label,'label_5',text=' A: '),
18 W(tk.Entry,'entry_5',width=5,expand=tk.NO,fill=tk.NONE),
19 W(tk.Label,'label_6',text=' B: '),
20 W(tk.Entry,'entry_6',width=5,expand=tk.NO,fill=tk.NONE),
21 W(tk.Label,'label_7',text=' C: '),
22 W(tk.Entry,'entry_7',width=5,expand=tk.NO,fill=tk.NONE),
23 W(tk.Label,'label_8',text=' D: '),
24 W(tk.Entry,'entry_8',width=5,expand=tk.NO,fill=tk.NONE)),
25 W(tk.Entry,'output'),
26 W(tk.Button,'button',text = 'Поехали',height=1,width=1,command=lambda: function(arguments))]
27 frame = Col(widget_list = layout)
28 frame.build(root)
29 frame.control('entry_1').insert(0,"12")
30 frame.control('entry_2').insert(0,"79")
31 frame.control('output').insert(0,"Текстовое поле")
32 root.mainloop()