Program doesn't work completely when run outside eclipse
Question: I have a small python application, which uses pyttsx for some text to speech.

How it works: simply say whatever is there in the clipboard.

The program works as expected inside eclipse. But if run on cmd.exe it only
works partly if the text on the clipboard is too large(a few paras). Why ?

when run from cmd, it prints statements , but the actual 'talking' doesn't
work(if the clipboard text is too large

Here is a of the program part which actually does the talking: As can be seen
the 'talking' part is handled inside a thread.

    
    
    def saythread(queue , text , pauselocation, startingPoint):
        saythread.pauselocation = pauselocation
        saythread.pause = 0 
        saythread.engine = pyttsx.init()      
        saythread.pausequeue1 = False
    
        def onWord(name, location, length):      
            saythread.pausequeue1  = queue.get(False) 
            saythread.pause = location
            saythread.pauselocation.append(location)
    
            if saythread.pausequeue1 == True :
                saythread.engine.stop()
    
        def onFinishUtterance(name, completed):
            if completed == True:
                os._exit(0)            
    
        def engineRun():
    
            if len(saythread.pauselocation) == 1:
                rate = saythread.engine.getProperty('rate')
                print rate 
                saythread.engine.setProperty('rate', rate-30)
            textMod = text[startingPoint:]
    
            saythread.engine.say(text[startingPoint:])
            token = saythread.engine.connect("started-word" , onWord )
            saythread.engine.connect("finished-utterance" , onFinishUtterance )
            saythread.engine.startLoop(True)
    
        engineRun()
    
        if saythread.pausequeue1 == False:
            os._exit(1) 
    
    
    def runNewThread(wordsToSay, startingPoint):    
        global queue, pauselocation
        e1 = (queue, wordsToSay, pauselocation, startingPoint)
        t1 = threading.Thread(target=saythread,args=e1)
        t1.start()
    
    #wordsToSay = CLIPBOARD CONTENTS
    runNewThread(wordsToSay,0)
    

Thanks

Edit: I have checked than the python version used is the same 2.7 . The
command used to run the program in cmd : `python
d:\python\play\speech\speechplay.py`


Answer: Checked that the problem is not in the code that reads the text from the
clipboard.

You should check if your eclipse setup specifies custom environment variables
for the project which do not exist outside Eclipse. Especially:

  * PYTHONPATH (and also additional projects on which your program could depend in your setup)
  * PATH

Use

    
    
    import os
    print os.environ['PATH']
    print os.environ['PYTHONPATH']
    

at the beginning of your program to compare both settings.

Misc stylistic advices:

  * don't use `os._exit`, prefer `sys.exit` (you should only use `os._exit` in a child process after a call to `os.fork`, which is not available on Windows)

  * I think a `threading.Event` would be more appropriate than a `queue.Queue`

  * I'd use a subclass approach for the thread with methods rather than a function with inner functions 

For example:

    
    
    import threading
    import sys
    import pyttsx
    
    class SayThread(threading.Thread):
    
        def __init__(self, queue, text, pauselocation, startingPoint, debug=False):
            threading.Thread.__init__(self)
            self.queue = queue
            self.text = text
            self.pauselocation = pauselocation
            self.startingPoint = startingPoint
            self.pause = 0
            self.engine = pyttsx.init(debug=debug)
            self.pausequeue1 = False
    
        def run(self):
            if len(self.pauselocation) == 1:
                rate = self.engine.getProperty('rate')
                print rate
                self.engine.setProperty('rate', rate-30)
            textMod = self.text[self.startingPoint:]
            self.engine.say(self.text[self.startingPoint:])
            self.engine.connect("started-word", self.onWord )
            self.engine.connect("finished-utterance", self.onFinishUtterance )
            self.engine.startLoop(True)
            if self.pausequeue1 == False:
                sys.exit(1)
    
        def onWord(self, name, location, length):
            self.pausequeue1  = self.queue.get(False)
            self.pause = location
            self.pauselocation.append(location)
            if self.pausequeue1 == True :
                self.engine.stop()
    
        def onFinishUtterance(self, name, completed):
            if completed == True:
                sys.exit(0)
    
    
    def runNewThread(wordsToSay, startingPoint):
        global queue, pauselocation
        t1 = SayThread(queue, wordsToSay,
                              pauselocation, startingPoint)
        t1.start()
    
    #wordsToSay = CLIPBOARD CONTENTS
    runNewThread(wordsToSay,0)
    

