Seite 1 von 1

Tkinter stürzt nach Event ab

Verfasst: Freitag 25. Februar 2005, 10:28
von Matu
Hi,

ich versuche gerade eine Anwendung zu schreiben, die Sprache erkennt und in einem Textfeld in Tkinter das Erkannte ausgibt. Leider wird das Event der Spracherkennung nur in der Klasse ContextEvents ausgeführt. Versucht man aus dieser Klasse heraus auf eine Methode in Tkinter der Klasse dictation zuzugreifen stürzt die GUI ab und macht nichts mehr.

Was mache ich falsch, oder gibt es vieleicht andere Lösungen?

Code: Alles auswählen

from win32com.client import constants
import win32com.client
import pythoncom
from Tkinter import *

class dictation:
    """ Initialize the speech recognition with the passed in list of words """
    def __init__(self):
        self.test = 'test'
        self.speaker = win32com.client.Dispatch("SAPI.SpVoice")
        self.listener = win32com.client.Dispatch("SAPI.SpSharedRecognizer")
        self.context = self.listener.CreateRecoContext()
        self.grammar = self.context.CreateGrammar(1) 
        self.grammar.DictationSetState(1)
        self.eventHandler = ContextEvents(self.context)
        self.say("Started successfully")
	self.fenster = Tk()
        self.text = Text(self.fenster)
        self.text.pack()

        #self.eventHandler.init(self)
        
        self.fenster.mainloop()

    def say(self, phrase):
        self.speaker.Speak(phrase)
    def addMenueleiste(self):
        self.menueleiste = Menu(self.fenster)
        self.fenster.configure(menu=self.menueleiste)
    def addDateimenue(self):
        self.dateimenue=Menu(self.menueleiste)
        self.dateimenue.add_command(label='Ende', command=self.beenden)
        self.menueleiste.add_cascade(label="Datei", menu=self.dateimenue)
    def beenden(self):
        self.fenster.destroy()

   # **** Hier stürzt TKinter ab, nachdem die Methode aus der Klasse 
   #ContextEvents aufgerufen wurde und den Befehl insert ausführt ***

    def say_hi(self, text):
        self.text.insert(END, text)

class ContextEvents(win32com.client.getevents("SAPI.SpSharedRecoContext")):
    def init(self, obj):
        self.obj = obj
    def OnRecognition(self, StreamNumber, StreamPosition, RecognitionType, Result):
        newResult = win32com.client.Dispatch(Result)
        print "You said: ",newResult.PhraseInfo.GetText()
        self.obj.say_hi(newResult.PhraseInfo.GetText())
    
if __name__=='__main__':
    speechReco = dictation()
danke schonmal vorweg.

Verfasst: Freitag 25. Februar 2005, 12:23
von mawe
Hi!

Sag mal ist das nicht haargenau der selbe Code den Du schon im Allgemeinen Forum gezeigt hast, mit haargenau der selben Frage? :evil:

Gruß, mawe

Sorry

Verfasst: Freitag 25. Februar 2005, 13:19
von Matu
da hast du recht. der grund dafür, hier mein problem nochmal anzusprechen, ist, dass ich glaube das tkinter das problem verursacht. und dann wäre ich ja im allgemeinen forum falsch aufgehoben. von mir aus kann der andere thread auch wieder gelöscht werden.

Verfasst: Freitag 25. Februar 2005, 13:42
von CM
Was mawe meint: Es ist schlechter Stil ein Doppelposting zu machen und bringt mehr Durcheinander als es hilft.

Schaue Dir mal die Ankündigung "Vor dem Posten lesen" in jedem Forum an. Dort steht auch, wie man seinen Post verfassen soll, so daß es wahrscheinlicher ist, eine gute Antwort zu bekommen.
Tut mir leid, von Tkinter hab ich keine Ahnung, aber einen Tipp will ich Dir trotzdem geben: Was gibt es denn für eine Fehlermeldung, wenn Dein Programm abstürzt? Solche Fehlermeldungen sind oft sehr hilfreich zur Behebung des Fehlers.

Viel Glück beim Beheben Deines Problems!

Gruß,
Christian

@mawe: Entschuldige, wenn ich Dir hier Worte in den Mund legte :(

Verfasst: Freitag 25. Februar 2005, 13:44
von Milan
Das mit dem doppelposting ist schon geregelt (hat im Allgemeinem um Löschung geboten --> hab ich dann auch mal gemacht). Generell ist es aber besser einfach um eine Verschiebung des Threads anzufragen, wie es auch in dem Regeln "Vor dem Posten lesen" steht (thx @CM).

Verfasst: Freitag 25. Februar 2005, 16:27
von mawe
Hi!
CM hat geschrieben: @mawe: Entschuldige, wenn ich Dir hier Worte in den Mund legte
Kein Problem. Da ich ja bekanntermassen faul bin, ist's mir nur recht wenn Du für mich sprichst :D

Ich finde es wäre besser gewesen diesen Thread hier zu löschen, weil Blackbird im Allgemeinen F. schon einen Tipp gegeben hat (soweit ich mich erinnern kann). Na egal, so schlimm is das auch wieder nicht :wink:

@Matu:
Naja, besonders viel werd ich Dir nicht helfen können, weil ich die win32com-Module nicht kenne. Aber (und das hat Blackbird auch schon gesagt), in der Klasse ContextEvents sollte es doch def __init__ heissen, oder?

Gruß, mawe

Verfasst: Freitag 25. Februar 2005, 18:43
von Matu
Hallo,

sorry nochmal für die Umstände.

Die def init(self, obj) ist eine einfache Methode, die oben einfach aufgerufen wird. Mit def __init__ habs ich auch ausprobiert, dann werden die events aber nicht mehr ausgelöst.

Ich nehme an, dass das Problem in der mainloop von Tkinter liegt. Diese ist ja normalerweise idle, und reagiert nur auf Buttons, Texteingaben usw.
Ist es vieleicht möglich ein neues event hinzuzügen, oder ein Tkinter event selbst auszulösen, welches dann eine Methode ausführt und das Textfeld aktualisiert.
Oder kann man die mainloop so umschreiben, dass sie eine Variable checkt, und wenn diese sich ändert, das Textfeld aktualisiert wird.

Verfasst: Dienstag 1. März 2005, 23:45
von matu
Hallo,

das Problem ist erstmal gelöst. Habe es mit einem unsichtbaren Button gemacht, der eine Funktion aufruft. Diese Funktioniert ruft dann wiederum nach einem bestimmten Zeitintervall den Butten wieder auf. Wenn nun Text erkannt wurde, wird die Variable sr.rec auf true gesetzt und der Text wird ausgegeben.

Code: Alles auswählen

        # invisible button, usage:updating
        self.button=Button(master,text='Count',command=self.start)
        self.startbutton=Button(master,text='START',command=self.x)
        self.startbutton.pack(side='bottom',fill='both')
        #self.button.invoke() #you can also start counting with __init__
        mainloop()
        
    def x(self):
        self.button.invoke()
        self.startbutton.config(state='disabled')

    def start(self):
        self.button.after(1500,self.button.invoke)
        if (sr.rec=="true"):
            self.text1.insert(END, (" "+ sr.text))
            sr.rec="false"
vieleicht hilfts ja jemand anderem weiter

Edit (XT@ngel): Code in Python Tags gesetzt.