tVector - надстройка над диспетчером pack() позволяющая располагать виджеты в виде "векторов" - строк или столбцов. Черезвычайно удобная вещь, оставляющая в прошлом мороку с расстановкой элементов на сложных формах. Несколько модифицирована чтобы можно было создавать список виджетов в цикле и передавать параметры упаковщика EXPAND и FILL для каждого конкретного виджета. [[attachment:vectors.jpg]] Пример встроен в сам скрипт. {{{#!highlight python """ Convenience layer for Tkinter. Allows window specifications to be created with far less, and much more readable code, than doing it by hand. Contains classes Row and Col, for building rows and columns of widgets, and building these into a live frame. """ import Tkinter from Tkinter import * class Vector(Frame): """ Tkinter vectors. A helper class for the easy creation and use of Tkinter layouts. (don't use this class directly - you should use the derived 'Row' and 'tVer' classes instead) For a working example, see this module's docstring """ def __init__(self, direction, *widgets, **kwds): """ Creates an array of widgets (or widget vectors) Best not to use this class directly - use one of the derived classes 'HOR' or 'VER' instead. """ if direction == 'right': self.packside = LEFT else: self.packside = TOP if kwds.has_key('widget_list'): self.widlist = kwds['widget_list'] del kwds['widget_list'] else: self.widlist = widgets self.kwds = kwds self.wids = {} # populate this during build def build(self, parent, **kw): """ Recursively descend through the widgets list, and construct/pack the window structure """ self.wids = {} if kw.has_key('fill'): fill = kw['fill'] del kw['fill'] else: fill = BOTH if kw.has_key('expand'): expand = kw['expand'] del kw['expand'] else: expand = YES # construct Frame for this vector #Frame.__init__(self, parent, self.kwds) Frame.__init__(self, parent, self.kwds) self.pack(side=self.packside, fill=fill, expand=expand) for wid in self.widlist: if isinstance(wid, Vector): wname = None wref = wid.build(self) self.wids.update(wid.wids) else: wcls = wid['class'] wname = wid['name'] wargs = wid['args'] wkwds = wid['kwds'] if wkwds.has_key('fill'): fill = wkwds['fill'] del wkwds['fill'] else: fill = BOTH if wkwds.has_key('expand'): expand = wkwds['expand'] del wkwds['expand'] else: expand = YES wref = wcls(self, *wargs, **wkwds) wref.pack(side=self.packside, fill=fill, expand=expand) if wname: self.wids[wname] = wref return self def control(self, widname=None, **kwds): """ Versatile method. Looks up component widgets by name. If any keywords are supplied, the widget's config() method will be called with these keywords. 3 ways of using: - with no arguments at all, returns a list of widget names - with just a widget name argument, returns a ref to that widget - with widget name and some keywords, calls config() on that widget and passes the given keywords. Examples: # get a list of widgets for vector 'mywin' widgets = mywin.wid() # get a handle to the widget 'label1' mylabel = mywin.wid('label1') # change the text of 'label1' mywin.wid('label1', text="Different text for label1") """ if not widname: return self.wids.keys() else: try: wid = self.wids[widname] if len(kwds) > 0: wid.config(**kwds) else: return self.wids[widname] except: raise AttributeError class Row(Vector): """ Creates a horizontal vector of widgets. For usage info, refer to Vector docstring """ def __init__(self, *widgets, **kwds): """ Constructor for Row - a horizontal vector of widgets Arguments: - widget1 - widget2 - ... Each widget should be either be something returned from W, or a Row or Col instance. For an example, refer to docstring for Vector class """ Vector.__init__(self, 'right', *widgets, **kwds) class Col(Vector): """ Creates a vertical column of widgets. For usage info, refer to Vector docstring """ def __init__(self, *widgets, **kwds): """ Constructor for Row - a vertical vector of widgets Arguments: - widget1 - widget2 - ... Each widget should be either be something returned from W, or a Row or Col instance. For an example, refer to docstring for Vector class """ Vector.__init__(self, 'down', *widgets, **kwds) def W(widclass, widname, *args, **kwds): """ Helper function for Row and Col classes. Generates a widget entry and translates it into a dict that can be fed straight to the Row and Col constructors. Refer to the Vector docstring for more info. Arguments: - widclass - a widget class object that behaves like normal tk widgets - widname - name to give to this widget (accessible later via Row.wid and Col.wid methods) - extra arguments are passed to the widget constructor Keywords: - anything you give gets passed straight to widget constructor Example: W(Tkinter.Button, 'mybutton1', text="Button 1") """ return {'name':widname, 'class':widclass, 'args':args, 'kwds':kwds} class mywin: def __init__(self, parent): self.layout = Col(W(Label, 'L1', text="Window Heading", font="helvetica 16 bold"), W(Checkbutton, 'Chk1', text="A checkbutton"), Row(W(Button, 'but1', text="Button 1", command=self.on_button1), W(Button, 'but2', text="Button 2", command=self.on_button2), W(Button, 'but3', text="Button 3", command=self.on_button3)), Row(W(Entry, 'fld1', text="field 1"), W(Entry, 'fld2', text="field 2"))) self.layout.build(parent) def on_button1(self): print "clicked button1" self.layout.control('but1', text="New Button1 label") def on_button2(self): print "clicked button2" self.layout.control('but1', text='Button 1') def on_button3(self): print "clicked button3" def mainloop(self): self.layout.mainloop() if __name__ == '__main__': root = Tk() app = mywin(root) app.mainloop() }}} Пример 2: {{{#!highlight python import Tkinter as tk from vector import * root = tk.Tk() root.title("Пример") layout = [W(tk.Label,'title',text='Заголовок',font=("Monotype Corsiva", 17, "bold italic")), Row( W(tk.Label,'label_1',text=' A: '), W(tk.Entry,'entry_1',width=5,expand=tk.NO,fill=tk.NONE), W(tk.Label,'label_2',text=' B: '), W(tk.Entry,'entry_2',width=5,expand=tk.NO,fill=tk.NONE), W(tk.Label,'label_3',text=' C: '), W(tk.Entry,'entry_3',width=5,expand=tk.NO,fill=tk.NONE), W(tk.Label,'label_4',text=' D: '), W(tk.Entry,'entry_4',width=5,expand=tk.NO,fill=tk.NONE)), Row( W(tk.Label,'label_5',text=' A: '), W(tk.Entry,'entry_5',width=5,expand=tk.NO,fill=tk.NONE), W(tk.Label,'label_6',text=' B: '), W(tk.Entry,'entry_6',width=5,expand=tk.NO,fill=tk.NONE), W(tk.Label,'label_7',text=' C: '), W(tk.Entry,'entry_7',width=5,expand=tk.NO,fill=tk.NONE), W(tk.Label,'label_8',text=' D: '), W(tk.Entry,'entry_8',width=5,expand=tk.NO,fill=tk.NONE)), W(tk.Entry,'output'), W(tk.Button,'button',text = 'Поехали',height=1,width=1,command=lambda: function(arguments))] frame = Col(widget_list = layout) frame.build(root) frame.control('entry_1').insert(0,"12") frame.control('entry_2').insert(0,"79") frame.control('output').insert(0,"Текстовое поле") root.mainloop() }}}