Program doesn't work completely when run outside eclipse [closed]
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
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
, prefersys.exit
(you should only useos._exit
in a child process after a call toos.fork
, which is not available on Windows)I think a
threading.Event
would be more appropriate than aqueue.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)
In fact, eclipse itself uses a commandline command to start it's apps.
You should check what command eclipse is giving to start the program. It might be a bit verbose, but you can start from there and test what is necessary and what isn't.
You can find out the commandline eclipse uses by running the program and then selecting the output in the debug window. Right-click it, select properties and you're done.
If you don't have a debug window you can open it window/show view/(other possibly)/debug.
turns out pythonpath wasn't set properly on my system. Edit: turns out pythonpath isn't the problem. I have no idea whats the problem. arghhhhhhhhhhhhhhhhhhhhhhhh
精彩评论