speechd-discuss
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[pygtk] Pygtk does not play nicely with speech-dispatcher


From: James Simmons
Subject: [pygtk] Pygtk does not play nicely with speech-dispatcher
Date: Thu, 24 Apr 2008 13:16:36 -0500

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
>
>





reply via email to

[Prev in Thread] Current Thread [Next in Thread]