Dave,

This is an abridged version of the code, concentrating on the important parts. Basically the gtk.TextView contains one page of the Etext, and the user presses the space key to start speech dispatcher going on the text. The words are spoken correctly, but the callbacks that *should* be invoked after each word never happen.

#! /usr/bin/env python
import pygtk
import gtk
import pango
import gobject
import speechd

page=0
PAGE_SIZE = 45
current_word = 0

class ReadEtextsActivity():
   def __init__(self):
       "The entry point to the Activity"

        # Setting up the speech-dispatcher client.
       self.client = speechd.SSIPClient('readetexts')
self.client._conn.send_command('SET', speechd.Scope.SELF, 'SSML_MODE', "ON")

   def next_word_cb(self, type, **kargs):
"callback that should be executed by speech dispatcher after each word"
       global current_word

       if current_word < len(self.word_tuples):
... code that highlights the next word in a gtk.TextView using pango ...
       return True
def keypress_cb(self, widget, event):
       "Respond when the user presses one of the arrow keys"
       keyname = gtk.gdk.keyval_name(event.keyval)
       if keyname == 'space':
self.client.speak(self.words_on_page, self.next_word_cb, (speechd.CallbackType.INDEX_MARK,
                       speechd.CallbackType.END))
           return True
       if keyname == 'plus':
           self.font_increase()
           return True
       if keyname == 'minus':
           self.font_decrease()
           return True
      ... use other keynames to scroll up and down, etc. ...
       return False

      ... various functions to scroll and page up and down, etc. ...
def delete_cb(self, widget, event, data=None):
       self.client.close()
       return False
def destroy_cb(self, widget, data=None):
       gtk.main_quit()

   def main(self, file_path):
       self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
       self.window.connect("key_press_event", self.keypress_cb)
       self.window.connect("delete_event", self.delete_cb)
       self.window.connect("destroy", self.destroy_cb)
       self.window.set_title("Read Etexts Activity")
       self.window.set_size_request(800, 600)
       self.window.set_border_width(0)
       self.read_file(file_path)
self.scrolled_window = gtk.ScrolledWindow(hadjustment=None, vadjustment=None)
       self.textview = gtk.TextView()
       self.textview.set_editable(False)
       self.textview.set_left_margin(50)
       self.textview.set_cursor_visible(False)
       buffer = self.textview.get_buffer()
       self.font_desc = pango.FontDescription("sans 12")
       font_size = self.font_desc.get_size()
       self.textview.modify_font(self.font_desc)
       self.show_page(0)
       self.scrolled_window.add(self.textview)
       self.window.add(self.scrolled_window)
       self.textview.show()
       self.scrolled_window.show()
       v_adjustment = self.scrolled_window.get_vadjustment()
       self.window.show()
       gtk.main()
if __name__ == "__main__":
   try:
       opts, args = getopt.getopt(sys.argv[1:], "")
       ReadEtextsActivity().main(args[0])
   except getopt.error, msg:
       print msg
       print "This program has no options"
       sys.exit(2)

I can provide the entire program if needed, but you'd need to have speech-dispatcher installed to run it. Note that if I do this:

       keyname = gtk.gdk.keyval_name(event.keyval)
       if keyname == 'space':
self.client.speak(self.words_on_page, self.next_word_cb, (speechd.CallbackType.INDEX_MARK,
                       speechd.CallbackType.END))
           while not done:
               gtk.events_pending()
               time.sleep(0.1)
           return True

then the callbacks *are* invoked, although the TextView is only updated after the final word is spoken so you only see the last word highlighted.

I am interested in learning more about your suggestion about gui_queue. If you can point me to a good article I'd be obliged. I'm going to try The Google for now and see if that turns up anything.

Thanks,

James Simmons


Dave Aitel wrote:

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Threading and pyGTK can be very complex - do your callbacks get called right out of your main thread (where I assume pyGTK's loop is running?)

It might be worth you posting a bit to the list. There are lots of programs that both do network processing and use PyGTK quite a bit, so it is possible. A simple fix to the threads will probably be in order. :>

FWIW, I would use this:

o Main thread running pyGTK with a gui_queue, that handles GUI events and also clears the gui_queue when it is idle. One of the gui_queue commands would be "trigger speech dispatcher callback" which would then use a speech dispatcher queue to tell that thread what to do. o speech dispatcher thread which then clears it's own queue and does callbacks based on that. You don't want the GUI thread doing speech, of course.

- -dave




_______________________________________________
pygtk mailing list   pygtk@daa.com.au
http://www.daa.com.au/mailman/listinfo/pygtk
Read the PyGTK FAQ: http://www.async.com.br/faq/pygtk/

Reply via email to