Software Design Spring 2007 For next time: 1) work on your project proposal. 2) finish any pending homeworks GUI Concepts ------------ Hierarchy of widgets. Automatic layout. Event-driven programming. Callbacks. Callbacks --------- 1) In widget_demo.py, I use the simplest form of a callback, a simple function: def press_me(): text = en.get() la2.configure(text=text) bu = g.bu(TOP, text='Press me', command=press_me) 2) In World.py, I use bound methods: self.bu(LEFT, text='Hello', command=self.hello) self.bu(LEFT, text='Quit', command=self.quit) A bound method is a method associated with a particular object, so when it is invoked, it is invoked on the object. In effect, you get one parameter free! 3) Another way to associate arguments with a callback is to wrap up the function and its arguments in an object. The Callable class is defined in Gui.py def set_color(color): ca.itemconfig(item2, fill=color) for color in ['red', 'green', 'blue']: g.mi(mb, color, command=Callable(set_color, color)) All three menu items use set_color as their callback, but they associate different arguments with it. So far, all the callbacks we have seen are command attributes. Later we will see how to associate callbacks with other events, which is called binding. Gather/scatter -------------- If a function takes a variable number of arguments, you can "gather" the arguments with the * operator. Try this in the interpreter: def foo(*args): print args foo(1) foo(1, 2) foo(1, 2, 3) You can also combine required and optional parameters: def bar(required, optional=-1, *the_rest): print required print optional print the_rest bar(1) bar(1, 2) bar(1, 2, 3) bar(1, 2, 3, 4) scatter ------- If you pass a sequence as an argument, it gets assigned to a single variable. def baz(a, b, c): print a, b, c t = (1, 2, 3) baz(t) Oops! Now try this: baz(*t) This can be handy, but it can also be confusing, since the * operator works differently in the context of an argument list (scatter) or a parameter list (gather). Project hunting --------------- Don't wait for a project to come to you! Here are some things you can do: 1) Look over the Python modules to see what kinds of capabilities are provided. One way to start a project is by exploring an interesting module. http://docs.python.org/modindex.html 2) Look for clients (on or off campus) and think about tools they could use. If you have taken UOCD, you know how to do this! 3) Design for yourself. Are there tools you wish you had? Is there material from another class that would lend itself to a project? 4) Behold the Vaults of Parnassus: http://www.vex.net/parnassus/ Great source of both modules to build on top of and ideas for things you could build yourself. 5) Get together and brainstorm. Get out the sticky notes and the blue foam! The group you brainstorm with doesn't have to be the group you work with. 6) Send ideas to the class mailing list. Two half-baked ideas sometimes make one fully-baked idea. Also, the traffic will help keep people thinking!