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/