Problem mit Funktionsaufruf

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Buell
User
Beiträge: 90
Registriert: Samstag 29. Oktober 2005, 14:17

Hallo zusammen,

bastel grad ein bißchen mit wxPython umher, allerdings geht es mir nicht um Darstellungsprobleme, deswegen hab ich meine Frage mal hier reingestellt.

Also folgende Situation:
ich habe mit wx.MDIParentFrame ein "Hauptfenster" erstellt. In diesem Hauptfenster wird dann ein ChildWindow (wx.MDIChildFrame) erzeugt. Dieses Child Window soll nun bei klick auf nen Button Daten an das Hauptfenster übergeben. Prinzipiell würde ich dafür mit import arbeiten um nen Link auf die Klasse im Hauptfenster zu erzeugen, aber das kann ich nicht tun, da das Hauptfenster dann neu geladen werden würde. Also muss ich irgendwie ohne import auskommen, doch wie...?

Ich könnte zwar ne zweite Klasse im Hauptfenster schreiben und die per import in das Child einbinden, bringt mich aber nicht weiter, da ich auf jeden Fall auf die Hauptklasse des Hauptfensters die Daten senden muss. Selbst mit der "Zwischenklasse" würde das Hauptfenster neu geladen werden.

Hilfeeee
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Kannst du nicht dem Child-Fenster eine Referenz (Variable) des Elternfensters mitgeben, wenn es erstellt wird?
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Gast

also da Child-Fenster bekommt ja den Link auf das Parent-Fenster mit:

Hauptfenster (Aufruf):

Code: Alles auswählen

win = wx.MDIChildFrame(self, -1, "Child Window: %d" % self.winCount)
prepare = __import__( "modules." + selected, globals(), locals(), selected )
canvas = prepare.MyFrame(win)
win.Show(True)
Child-Fenster:

Code: Alles auswählen

def __init__(self, parent, id = -1, size = wx.DefaultSize):
Aber da kann man dann ja trotzdem nicht auf parent.irgendwas zugreifen, dazu müsste ja im Child-Fenster auch noch die genaue Klasse bekannt sein.

Hab schon hin und her experimentiert mit Events und Threads, aber noch keine akzeptable Lösung gefunden.

Edit (Leonidas): Code in Python-Tags gesetzt.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Könntest du mal ein komplettes Minimalbeispiel posten?
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Buell
User
Beiträge: 90
Registriert: Samstag 29. Oktober 2005, 14:17

Hallo also Beispiel, ich nehme einfach mal das Haupt- und das Child-Fenster, da fehlen dann noch einige Module, aber darum geht es ja nicht.

Also MainWindow:

Code: Alles auswählen

from wxPython.wx import *
import  wx
import  pyCfg
import images
import INandOUT
# import threading
# import thread


SHOW_BACKGROUND = 1

#----------------------------------------------------------------------
ID_Config_TTS  = wx.NewId()
ID_Config_SR  = wx.NewId()
ID_Exit = wx.NewId()
ID_Agent_Show = wx.NewId()
ID_Agent = wx.NewId()

# myEVT_SPEAK_OUT = wx.NewEventType()
# EVT_SPEAK_OUT = wx.PyEventBinder(myEVT_SPEAK_OUT, 1)

#----------------------------------------------------------------------

class MyParentFrame(wx.MDIParentFrame):
    def __init__(self):
        # initialise window
        wx.MDIParentFrame.__init__(self, None, -1, "Speech Tool", size=(600,400))

        # set class globals
        self.cfg = pyCfg.pySapiCfg()
        self.modules = self.cfg.getModules()
        self.TTS_list = self.cfg.getMyTTS()
        self.SR_list = self.cfg.getMySR()

        # set defaults
        self.cfg.writeCSV('tts',self.TTS_list[0])
        self.cfg.writeCSV('sr',self.SR_list[0])
        self.cfg.writeCSV('msagent','false')

        # define Module menu ID's
        self.ID_Module = []
        for item in self.modules:
            self.ID_Module.append(wx.NewId())

        # define TTS menu ID's
        self.ID_TTS = []
        for item in self.TTS_list:
            self.ID_TTS.append(wx.NewId())

        # define SR menu ID's
        self.ID_SR = []
        for item in self.SR_list:
            self.ID_SR.append(wx.NewId())

        # for testing only
        print "init"

        # end testing
        
        self.winCount = 0

        # Create Menu Modules
        menu_module = wx.Menu()
        i = 0
        for item in self.modules:
            menu_module.Append(self.ID_Module[i], item)
            i += 1
        menu_module.AppendSeparator()
        menu_module.Append(ID_Exit, "E&xit")
        menubar = wx.MenuBar()
        menubar.Append(menu_module, "&Modules")

        # Create Menu TTS
        menu_TTS = wx.Menu()
        i = 0
        for item in self.TTS_list:
            menu_TTS.Append(self.ID_TTS[i], str(item), kind=wx.ITEM_RADIO)
            i += 1
        menu_TTS.AppendSeparator()
        menu_TTS.Append(ID_Config_TTS, "More &Settings")
        menubar.Append(menu_TTS, "&TextToSpeech")

        # Create Menu SR
        menu_SR = wx.Menu()
        i = 0
        for item in self.SR_list:
            menu_SR.Append(self.ID_SR[i], item, kind=wx.ITEM_RADIO)
            i += 1
        menu_SR.AppendSeparator()
        menu_SR.Append(ID_Config_SR, "More &Settings")
        menubar.Append(menu_SR, "&SpeechRecognition")

        # Create Menu Properties
        menu_props = wx.Menu()
        menu_props.Append(ID_Agent_Show, "Show MSAgent", kind=wx.ITEM_CHECK)
        menu_props.Append(ID_Agent, "MSAgent Settings")
        menubar.Append(menu_props,"&Properties")
        
        self.SetMenuBar(menubar)

        self.CreateStatusBar()

        # Bind Events
        i = 0
        for item in self.modules:
            self.Bind(wx.EVT_MENU, self.OnNewWindow, id=self.ID_Module[i])
            i += 1
        self.Bind(wx.EVT_MENU, self.OnExit, id=ID_Exit)
        i = 0
        for item in self.TTS_list:
            self.Bind(wx.EVT_MENU, self.OnChangeTTS, id=self.ID_TTS[i])
            i += 1
        self.Bind(wx.EVT_MENU, self.OnMoreSettingsTTS, id=ID_Config_TTS)
        i = 0
        for item in self.SR_list:
            self.Bind(wx.EVT_MENU, self.OnChangeSR, id=self.ID_SR[i])
            i += 1
        self.Bind(wx.EVT_MENU, self.OnMoreSettingsSR, id=ID_Config_SR)

        if SHOW_BACKGROUND:
            self.bg_bmp = images.getGridBGBitmap()
            self.GetClientWindow().Bind(
                wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground
                )

    def OnExit(self, evt):
        self.Close(True)


    def OnNewWindow(self, evt):
        # get Text of Selection in Module Menu
        id = evt.GetId()
        item = self.GetMenuBar().FindItemById(id)
        selected = str( item.GetText() )
        self.winCount = self.winCount + 1
        win = wx.MDIChildFrame(self, -1, "Child Window: %d" % self.winCount)
        prepare = __import__( "modules." + selected, globals(), locals(), selected )
        canvas = prepare.MyFrame(win)
        win.Show(True)

    def OnChangeTTS(self, evt):
        # get Text of Selection in TTS Menu
        id = evt.GetId()
        item = self.GetMenuBar().FindItemById(id)
        selected = item.GetText()
        self.cfg.writeCSV('tts', selected)

    def OnChangeSR(self, evt):
        # get Text of Selection in SR Menu
        id = evt.GetId()
        item = self.GetMenuBar().FindItemById(id)
        selected = item.GetText()
        self.cfg.writeCSV('sr', selected)

    def OnMoreSettingsTTS(self, evt):
        print "More Settings TTS"

    def OnMoreSettingsSR(self, evt):
        print "More Settings SR"


    def OnEraseBackground(self, evt):
        dc = evt.GetDC()

        if not dc:
            dc = wx.ClientDC(self.GetClientWindow())

        # tile the background bitmap
        sz = self.GetClientSize()
        w = self.bg_bmp.GetWidth()
        h = self.bg_bmp.GetHeight()
        x = 0
        
        while x < sz.width:
            y = 0

            while y < sz.height:
                dc.DrawBitmap(self.bg_bmp, x, y)
                y = y + h

            x = x + w

    def SpeakOut(self):
        print "Juhu"
    
class COM:
    def __init__(self):
        self.TTS = INandOUT.LoadTTS()
        print "init COM"

    def OUTPUT(self, text):
        # self.TTS.TTSoutput(text)
        # wxEvtHandler.ProcessEvent(EVT_SPEAK_OUT)
        # window.__class__.SpeakOut()
        self.TTS.TTSoutput(text)
        return None

    def INPUT(self, text):
        return None
        


class test:
    def __init__(self):
        print "init test class"
    def text(self, text):
        print text


#----------------------------------------------------------------------

if __name__ == '__main__':
    class MyApp(wx.App):
        def OnInit(self):
            wx.InitAllImageHandlers()
            frame = MyParentFrame()
            frame.Show(True)
            self.SetTopWindow(frame)
            return True


    app = MyApp(False)
    app.MainLoop()
und Beispiel Child-Fenster (einfach ein Textfeld und ein Button):

Code: Alles auswählen

import  wx
import SpeechTool

class MyFrame(wx.ScrolledWindow):
    def __init__(self, parent, id = -1, size = wx.DefaultSize):

        self.COM = SpeechTool.COM()
        # self.MyParentFrame = parent
        
        wx.ScrolledWindow.__init__(self, parent, id, (0, 0), size=size, style=wx.SUNKEN_BORDER)

        self.textbox = wx.TextCtrl(self, -1, "This is the Sound of my Voice", size=(200, -1))
        self.textbox.SetPosition((15,15))
        

        button = wx.Button(self, 1003, "Sprich")
        button.SetPosition((15, 50))
        self.Bind(wx.EVT_BUTTON, self.OnButton, button)
        self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)


    def OnButton(self, event):
        # self.MyParentFrame.OUTPUT(self.textbox.GetValue())
        self.COM.OUTPUT(self.textbox.GetValue())
        # wx._windows.MDIParentFrame.SpeakOut()
        return None

    def OnCloseWindow(self, event):
        self.Destroy()
Wie vielleicht zu erkennen geht es bei dem Programm um Spracherkennung und Sprachausgabe über verschiedene SAPI Engines (momentan 4+5) und die Möglichkeit der Einbindung von x-beliebigen Python Modulen

Das Problem besteht darin, dass das Modul der Sprachausgabe möglichst nur einmal initialisert werden soll (INandOUT) und dann für alle Module die als Child-Fenster geladen werden zur Verfügung steht. Hab es bis jetzt so am laufen, dass bei jedem neuen Child-Fenster ein neues SprachausgabeModul initialisiert wird. Für die Spracherkennung ist das absolut sinnvoll, da man für jedes Modul eine andere Grammatik laden kann, aber für die Ausgabe komplett überflüssig.

Edit (Leonidas): Code in Python-Tags gesetzt.
Antworten