Software Design Lecture Notes Fall 2004 Tips on Chatters and Rooms -------------------------- One way to make up a name for your Chatter: from random import randrange self.login = os.getlogin() self.name = 'chatter_%s%d' % (self.login, randrange(1000)) In working on your Chatter and Room implementations, you might find it tricky to handle KeyboardInterrupts correctly. As an example, here is the version of stoppableLoop from RemoteObject.py def stoppableLoop(self): # run handleRequests until another thread clears self.running self.running = 1 while self.running: self.demon.handleRequests(0.1) self.cleanup() If this ends normally, it cleans up after itself, but if the user presses Control-C while the thread is running the loop, it might exit without cleaning up. One way to fix that is with the finally clause: def stoppableLoop(self): # run handleRequests until another thread clears self.running self.running = 1 try: while self.running: self.demon.handleRequests(0.1) finally: self.cleanup() The finally clause always executes, whether an exception occurs or not. For more details, I recommend "Python in a Nutshell". An alternative is to use an except clause, as I did in my implementation of Chatter: try: chat.mainloop() except: chat.quit() (type, value, traceback) = sys.exc_info() if type != KeyboardInterrupt: raise type, value If an exception occurs while mainloop is running, we execute quit (which executes cleanup). If the exception is anything other than a KeyboardInterrupt, we "propagate" the exception by re-raising it. See if you prove, by inspection of your code, that the program cannot exit (either normally or with an exception) without cleaning up! Scrollable text --------------- I've added a couple of widgets to World.py You have to download the newest version to get them. Here's the new code # scrollbar def sb(self, side=TOP, fill=NONE, expand=0, anchor=CENTER, **options): return self.widget(Scrollbar, side, fill, expand, anchor, **options) class ScrollableText: def __init__(self, gui, side=TOP, fill=NONE, expand=0, anchor=CENTER, **options): self.frame = gui.fr(side, fill, expand, anchor, **options) self.scrollbar = gui.sb(RIGHT, fill=Y) self.text = gui.te(LEFT, wrap=WORD, yscrollcommand=self.scrollbar.set) self.scrollbar.config(command=self.text.yview) gui.endfr() # scrollable text # returns a ScrollableText object that contains a frame, a # text entry and a scrollbar. # note: the options provided to st apply to the frame only; # if you want to configure the other widgets, you have to do # it after invoking st def st(self, side=TOP, fill=NONE, expand=0, anchor=CENTER, **options): return self.ScrollableText(self, side, fill, expand, anchor, **options) Here's how you can create a ScrollableText widget: st = self.st() And here's how you can add text to it: st.text.insert(END, message + '\n')