开发者

Program doesn't work completely when run outside eclipse [closed]

This question is unlikely to help any future visitors; it is only relev开发者_JS百科ant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center. Closed 11 years ago.

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


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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜