Tkinter stürzt nach Event ab

Fragen zu Tkinter.
Antworten
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.
mawe
Python-Forum Veteran
Beiträge: 1209
Registriert: Montag 29. September 2003, 17:18
Wohnort: Purkersdorf (bei Wien [Austria])

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
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.
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

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 :(
Milan
User
Beiträge: 1078
Registriert: Mittwoch 16. Oktober 2002, 20:52

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).
mawe
Python-Forum Veteran
Beiträge: 1209
Registriert: Montag 29. September 2003, 17:18
Wohnort: Purkersdorf (bei Wien [Austria])

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