tVector - надстройка над диспетчером pack() позволяющая располагать виджеты в виде "векторов" - строк или столбцов. Черезвычайно удобная вещь, оставляющая в прошлом мороку с расстановкой элементов на сложных формах. Несколько модифицирована чтобы можно было создавать список виджетов в цикле и передавать параметры упаковщика EXPAND и FILL для каждого конкретного виджета.

vectors.jpg

Пример встроен в сам скрипт.

   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()

Пакеты/GUI/Tkinter/tVector (последним исправлял пользователь Роман 2010-11-16 11:02:13)