#!/usr/bin/env python # authors: Matthieu Bec, Francois Rigaut # helloworld.py # import necessary modules import gtk import gtk.glade import sys import gobject import os, fcntl, errno # define the class class helloworld: def destroy(self, wdg, data=None): self.py2yo('quit') # gtk.main_quit() # we'll call this from yorick before it quits. def __init__(self,helloworldtop): self.helloworldtop = helloworldtop # read GUI definition self.glade = gtk.glade.XML(os.path.join(self.helloworldtop,'helloworld.glade')) # handle destroy event (so that we can kill the window through window bar) self.window = self.glade.get_widget('window1') if (self.window): self.window.connect('destroy', self.destroy) # autoconnect to callback functions # this will automatically connect the event handler "on_something_event" # to the here-defined function of the same name. This avoid defining a # long dictionary that serves the same purpose self.glade.signal_autoconnect(self) # set stdin non blocking, this will prevent readline to block # stdin is coming from yorick (yorick spawned this python process) fd = sys.stdin.fileno() flags = fcntl.fcntl(fd, fcntl.F_GETFL) fcntl.fcntl(fd, fcntl.F_SETFL, flags | os.O_NONBLOCK) # ... and add stdin to the event loop (yorick input pipe by spawn) gobject.io_add_watch(sys.stdin,gobject.IO_IN|gobject.IO_HUP,self.yo2py,None) # run: realize the interface, start event management gtk.main() # callback functions # This is the important, user-defined heart of this file. # here, you define the function that will be called when an event is raised # (read: happens): a button is pressed, a slider is moved, you enter a # drawingarea or move the cursor, etc... Just define a handler (callback) of # the same name in the glade UI definition (see signals) and you're done. def on_helloworld_clicked(self,wdg): self.py2yo('write "Hello World!"') # minimal wrapper for yorick/python communication # This is really internal to the yorick/python communication and you should # not have to fiddle with it def py2yo(self,msg): # sends string command to yorick sys.stdout.write(msg+'\n') sys.stdout.flush() def yo2py(self,cb_condition,*args): if cb_condition == gobject.IO_HUP: raise SystemExit, "lost pipe to yorick" # handles string command from yorick # note: inidividual message needs to end with \n for proper ungarbling while 1: try: msg = sys.stdin.readline() msg = "self."+msg exec(msg) except IOError, e: if e.errno == errno.EAGAIN: # the pipe's empty, good break # else bomb out raise SystemExit, "yo2py unexpected IOError:" + str(e) except Exception, ee: raise SystemExit, "yo2py unexpected Exception:" + str(ee) return True # check calling syntax (should not be a problem as it is always called # from yorick if len(sys.argv) != 2: print 'Usage: helloworld.py path_to_glade' raise SystemExit # get path to glade file helloworldtop = str(sys.argv[1]) # execute it top = helloworld(helloworldtop)