=============================== ``grail.widgets.gtools`` module =============================== .. include:: ../../version.h .. include:: ref.h .. contents:: Table of Contents :backlinks: top ----------- Description ----------- A set of convenience functions for building a Graphical User Interfaces (GUI) using Tkinter style widgets. This also includes the widgets provided by MineSightŪ Grail. This module differs from the other widget modules in so far as it provides functions only, as opposed to specialized widgets. --------- Functions --------- :df:`displaychildren(streamout, children [, indentlevel])` Dumps a widgets children out to the stream. A debug function for displaying the children of a particular widget. This function will recursively traverse children of the children in the list of children. Arguments: :a:`streamout` : file-like object A standard python I/O object. An example would be :c:`sys.stdout` [#python-lib-sys]_. :a:`children` The list of children from a widget's :f:`winfo_children` call. :a:`indentlevel` Starting indent level, default is 0. .. Note:: The :a:`indentlevel` is incremented by 2 for each recursive step. :df:`drawarrow(canvas, foreground, direction, tag)` Draws an arrow onto the canvas. Credit to the algorithm for drawing arrows from the Pmw library [#pmw]_. Arguments: :a:`canvas` : :c:`Tkinter.Canvas` The :c:`Canvas` object to draw on. :a:`foreground` Color for the arrow itself. :a:`direction` Direction you want the arrow to point. The :a:`direction` must be one of: 'up', 'down', 'left', or 'right'. :a:`tag` A tag, so you can reference the arrow later on the canvas. Side-Effects: - Any object with the given tag gets deleted prior to the drawing. - Modifies the canvas object to contain the new arrow. :df:`geominfo(widget)` Returns the type and configuration for a geometry layout. Indicates what type of geometry layout was used: place, grid or pack. In addition it returns the configuration information used to perform the geometry layout. An example would be, .. Python:: w = GButton(root, text="test button!") geomtype, geominfo = gtools.geominfo(w) This returns a tuple of the form: (geometrytype, geometryinfo,). :a:`geometrytype` be one of: 'place', 'grid', or 'pack'. :df:`gridby(type, num, *args, **kws)` Allows you to grid multiple widgets by column or row. In general, this follows a basic scheme set out in :f:`makewidgets`. Say you had three lists of columns that you wanted to grid in one step. This function will apply the grid command to each widget in each of the lists. For example, say we had the following columns of widgets, .. Python:: # three columns of labels, None is used as a "empty" slot. widgets1 = (GLabel(...), GLabel(...),GLabel(...),) widgets2 = (GLabel(...), None, GLabel(...),) widgets3 = (GLabel(...), GLabel(...),GLabel(...),) then, lets say, we want the first row to stick to the east side of the column, and the rest to stick to the west side. To do this we use the list_xxx keyword to that will apply the keyword element to each widget column, so for our example we would do, .. Python:: stickyopts=('e', 'w', 'w',) Now, in our final call, we want to use :a:`padx` of 4 for every column. Since we apply it across all columns, we do not need to prepend \list_ to it. Finally the call would be, .. Python:: gtools.gridby('column', 3, widgets1, widgets2, widgets3, padx=4, list_sticky=stickyopts) Arguments: :a:`type` Either 'row' or 'column'. :a:`num` The number of rows or columns you want. :df:`makewidgets(parent, widget, numwidgets, **kws)` Makes a series of widgets with optionally varying configurations. A convenience function that allows you to make a series of widgets and optionally vary configuration parameters if you want. If you have a list of configuration options that you want to vary over the set of widgets, you prefix that configuration option with \list_. For example, say you want to quickly construct a list of three labels, you can either do the following, .. Python:: lbl1 = Label(parent, text='label1: ') lbl2 = Label(parent, text='label2: ') lbl3 = Label(parent, text='label3: ') then lay them out, or you can quickly assemble a list like this, .. Python:: texts = ("Label1: ", "Label2: ", "Label3: ",) labels = makewidgets(parent, Label, 3, list_text=texts) Then you can run list through a 'list layout' method such as :f:`packwidgets` or :f:`stdwidgetcolumns`. Another example would be, say we want to make all the backgrounds red, and still vary the text for each of the labels, then we would do something like this, .. Python:: labels = makewidgets(parent, Label, 3, list_text=texts, background='red') In this case, the 'background' configuration option will be applied to every label in the list, whereas the list_text option will vary across all three widgets. Returns a list of widgets. :df:`mapdefaults(keywords, defaultKeyVals)` Takes a set of default-value-pairs and begins mapping them to the keywords. Typically you would have a set of keywords that should have some default values, but if the user has already specified a value we do not want that value overwritten in the keywords dictionary. For example, consider the :a:`defaultKeyVals` as for a :c:`GRadio` button, .. Python:: _DEF_RADIO = (('align', 'vertical',), ('items', [],), ('rtv', None,), ('justify', Tkinter.LEFT,),) If the user defined the rtv value for their radio button, and no other value, then in the :c:`GRadio` we would have the following, .. Python:: keywords = {'rtv':} Now we want to ensure that the other 'default' values are inserted without overwriting the 'rtv' value. Well, this is the whole point of this function, .. Python:: mapdefaults(keywords, _DEF_RADIO) Finally, a tip, if you have a series of configuration parameters, as you might have in a complex composite widget, you can apply the defaults in one clean line like so, .. Python:: map(mapdefaults, (widget1keywords, widget2keywords, widget3keywords,), (_DEF_WIDGET1, DEF_WIDGET2, DEF_WIDGET3,)) Arguments: :a:`keywords` The dictionary to install default values into. :a:`defaultKeyVals` The sequence of key-value pairs to potentially install. Returns the updated keywords dictionary. :df:`nsplitframe(n, parent[, **kws])` A generalized form of :f:`splitframe`. Allows you to split a frame into n subframes. Equivalent to calling :f:`splitframe` on the resulting second frame. For example, the call, .. Python:: root = Tk() top, middle, bottom = nsplitframe(3, root, anchor='nw') is equivalent to, .. Python:: root = Tk() top, tempframe = splitframe(root, anchor='nw') middle, bottom = splitframe(tempframe, anchor='nw') You can see that this just performs a recursive split for n times on the spare :a:`tempframe`, and returns the resulting n split frames. Arguments: :a:`n` Number of subframes you want. :a:`parent` Parent frame for the subframes :a:`kws` Other keywords you would use in :f:`splitframe`. Returns: What is returned is a function of the value of n. - if :a:`n` <= 0 you will get an empty tuple. - if :a:`n` == 1 you will get the parent back inside a tuple. - if :a:`n` > 1 you will get :a:`n` frames back in a tuple with length :a:`n`. When :a:`n` > 1, the tuple of frames are ordered such that the first frame corresponds to the top most frame when :a:`orient` is 'horizontal' (default), and right most frame when :a:`orient` is 'vertical'. .. Note:: There is no check to ensure that :a:`n` is an integer and that parent is a frame. If by accident you switch these values around, this function essentially interprets it as a call with :a:`n` <= 0. :df:`packwidgets(widgetlist, **kws)` Applies the same pack configuration to a list of widgets. :df:`setgeometryanddeiconify(window, geom)` Sets the geometry on a window and de-iconifies it. The NT systems require a bit of a work-around that this function provides. Arguments: :a:`window` A window object that has a :f:`geometry` method. :a:`geom` A standard Tkinter geometry configuration string. :df:`splitframe(parent[, orient, **kws])` Splits a frame along the orientation direction Takes a master frame and splits that frame along either the 'horizontal' or 'vertical' directions and creating two more frames. Splitting is done via the pack geometry layout method. Some examples, .. Python:: # my working frames frame1 = Frame() frame2 = Frame() top, bottom = splitframe(frame1, padx=4, pady=4) left, right = splitframe(frame2, orient='vertical', pady=4) # cause an infinite loop; use grid on another widget in frame1 Label(frame1, text="Infinite").grid(row=0, column=1) Arguments: :a:`parent` : :c:`Tkinter.Frame` The parent frame that you want to split. :a:`orient` Orientation for the splitting. Can be 'horizontal' or 'vertical'. Default is 'horizontal'. :a:`kws` A set of keywords that you would like to apply to each of the split frame's pack geometry. For example, padx, pady, anchor, etc... You can not specify the side. Returns a tuple containing the two split frames. Returned as either (top, bottom) for 'horizontal' or (left, right) for 'vertical'. .. Note:: That all widgets inserted into the parent widget supplied must use the pack geometry, or a Tkinter infinite loop will occur. :df:`stdframepack(frame)` Applies a 'typical' pack to a frame. A convenience function, this helps to enforce a standard packing schematic for the :c:`Tkinter.Frame` (or :c:`GFrame`) widget. The standard configuration options can be found in this module's constant :d:`STD_FRAME_PACK`. :df:`stdgrouppack(groupwidget)` Applies a pack to the :c:`GGroup` widget. A convenience function, this just helps to enforce a standard packing schematic for the :c:`GGroup` widget. The standard configuration options can be found in this module's constant :d:`STD_GROUP_PACK`. In addition the interior frame is reconfigured to anchor to the northwest corner of the :c:`GGroup` widget. Remember that the interior is really another frame used to display widgets on. :df:`stdwidgetcolumns(widgetlabels, widgets)` Does a standard label/widget grid layout. Takes a list of :a:`widgetlabels` and a list of widgets and performs the standard label to the left side, input widget to the right side layout. Typically used in conjunction with :f:`makewidgets`. Arguments: :a:`widgetlabels` A sequence of labels widgets. :a:`widgets` A set of input widgets. A few remarks on this function, - All layout is done with grid, be careful not to mix different layouts on the same frame in order to avoid the Tkinter infinite loop. Typically it is recommended that you create an independent frame for use with this function. - The :a:`widgetlabels` do not necessarily have to be labels, they can be any widget that carries the grid method. - You can use :d:`None` as place holders, for example, if one part of your list doesn't have anything in the other part. :df:`walkpaneltree(root, func, arg)` Walks a panel tree configuration. Will walk through a panel configuration starting at the configuration's :a:`root`, and apply func(foldername, gitems, arg) to each folder. The traversal is in a breadth-wise fashion. For example, the following could be used to walk the panel configuration, .. Python:: import pprint from grail.widgets import * class ExamplePanel(GPanel): def makewidgets(self): pass subfolder = GFolder("Sub Folder", [GItem("Sub 1", ExamplePanel), GItem("Sub 2", ExamplePanel)]) folder = GFolder("Root", [subfolder, GItem("Root 1", ExamplePanel)]) # our "printing" function. def _print_callback(foldername, gitems, arg): print "foldername: %s" % (foldername) print "contents: %s" % (pprint.pprintformat(gitems)) walkpaneltree(folder, _print_callback, None) The :a:`arg` parameter may be used to store information during a traversal. For example, say you want to extract all the :c:`GItem` objects from the panel tree, but you do not care how it is done. Continuing with our example above you could do the following, .. Python:: def _extract_gitems(foldername, gitems, itemlist): itemlist += gitems # append new items to the end of the list. itemlist = [] walkpaneltree(folder, _extract_gitems, itemlist) pprint.pprint(itemlist) This item list would contain the "Sub 1", "Sub 2" and "Root 1" :c:`GItem` objects defined for the panel configuration tree. :df:`winrootcoords(window[, position])` Returns a x,y root coordinates for the given corner of a window. Given a position on a window, you can get the root coordinates. The root coordinates mean the coordinates relative to the desktop. Arguments: :a:`window` A Tkinter window object, should have winfo_* methods. :a:`position` One of 'ne', 'nw', 'se' or 'sw' corners that you want the coordinates for. ---- Data ---- :dd:`STD_FRAME_PACK` Standard configuration for packing frames. Provides useful defaults. :dd:`STD_GROUP_PACK` Standard configuration for a good packing of :c:`GGroup` widgets. ---------- References ---------- .. [#pmw] Pmw Python MegaWidgets. 5 August 2003. 3 August 2004. .. [#python-lib-sys] "sys -- System-specific parameters and functions" *Python Library Reference*. 30 May 2003. 3 August 2004.