GetEventObject() /

Steve Freedenburg wrote:

let's say I have 2 instances of a button on a frame.
And those 2 buttons are bound to an event.

___Snip___
I looked at how Robin's book did this sort of thing and came up with
    def onEvent(self, event):
        item = self.GetMenuBar().FindItemById(event.GetId())
        text = item.GetText()
        wx.MessageBox("You selected the '%s' item" % text)

# Run the program
if __name__ == "__main__":
    app = wx.PySimpleApp()
    frame = MyForm().Show()
    app.MainLoop()

</code>

Notice the GetMenuBar() and FindItemById() methods. You'll probably also
like the FindMenuItem() method (which I'm not using) helpful.

···

Subject: Re: [wxpython-users] GetEventObject() /
From: Mike Driscoll <mike@pythonlibrary.org>

-------------------
Mike Driscoll

Hi!

    In my case could not find the find method when I wrote mine which is
helpful as Mike pointed out. The other way is to make a copy of all the
menu's and storing
the ID of each. It is better to have the computer assign the id's instead of
making one, but my example does use sequential ID's which could run into
duplication.
    I discovered in my example that having all the menu's stored inside a
global list is another approach, but did not even know the find method
existed. In either case the dictionary you want to have located would also
have to use the ID as a key which I assume you are doing to be able to find
that dictionary.

    so take a look at my approach and I use the self.menuItems as the
storage place of all the menu's.
    My example only stores what is needed for the handler call and what it
needs and that is the text of the menu. Now that text also could be the key
for the dictionary, I guess depending on how you store your dictionaries...
    The menu text is the HotKey text and there is a built in function for
that as you will see when you go down to the OnMenu handler Call.

#LAST MODIFIED SUNDAY, AUGUST 10 2008
#ADDED MENUITEMS LIST FOR ID SEARCH.
#MODIFIED WEDNESDAY, JULY 23 2008
#CREATED TUPLES FOR ALL MENU ITEMS!
#ADDED MENUBAR_SETTINGS TO FIND SETTINGS PARMS.
#MODIFIED TUESDAY, JULY 22 2008
#ADDED OR WENT BACK TO SLIDER CONTROL FOR BETTER MOVEMENT USING PAGE UP AND
DOWN!
#ERASE ALL MAX AND MIN CHECKS INSIDE FUNCTION SETVOICE!
#MODIFIED MONDAY, JULY 21 2008
#ADDED SPIN CONTROL FOR VOICE SETTINGS!
#ADDED KEY EVENT FOR SPIN CONTROL SO ENTER KEY EXITS AND KILLS SPIN!
#MODIFIED THURSDAY, JULY 17 2008
#ADDED TTS2 A DICTIONARY OF VOICES TO CONTROL ANY TYPE OF VOICE, SAPI 4 OR
SAPI 5
#ADDED TTSP POINTER TO WHICH VOICE TO USE!
#ADDED CHANGE VOICE TOGGLE FUNCTION AND VOICE MENU ITEM FOR THE VOICE
CHANGE!
#MODIFIED TUESDAY, JULY 15 2008
#ADDED THE SAPI 4 ENGINE FOR EXTRA VOICES.
desc="""In the following example we use a sizer with vertical layout"""
#Editor.py
import wx
import os
#import errors2file
import Sapi5, Sapi4
tts5 = Sapi5.Create( {"name":"Mary"})
tts4 = Sapi4.Create( {"name":"Fred"})
#tts = tts5
TS4=4
TS5=5
TTS2 = {TS4:tts4, TS5:tts5}
purge = tts5._purge
async = tts5._async
punc = tts5._punc
ID=0
class MenuParms( object):
    def __init__(self, id4item, hk4item, khlp4item, handler4item):
        self.id4item = id4item
        self.hk4item = hk4item
        self.khlp4item = khlp4item
        self.handler4item = handler4item
class MainWindow( wx.Frame):
    def __init__(self, parent, id, title):
        self.ttsp = TS5
        self.tts = TTS2[ TS5]
        self.dirname=os.getcwd() #SEARCH FROM PRESENT DIRECTORY!
        self.filename=""
  #CREATING A TUPLE WITHIN A TUPLE FOR THE MENUBAR!
        self.items4menu = (
            ("File", (
            MenuParms(102, "&Open", " Open a file to edit", self.OnOpen),
            MenuParms(103, "&Save", " save file to disk", self.OnSave),
            MenuParms(104, "&Edit", " Do editing", self.Do_Edit),
            MenuParms(101, "&About", " Information about this program",
self.OnAbout),
            MenuParms(109, "E&xit", " Terminate the program", self.OnExit),
        ), #END OF FILE PARMS!
        ), #END OF FILE MENU!
        ("Voice", (
            MenuParms(202, "&Read", " Open a file to read",
self.OnWav2Read),
            MenuParms(203, "&Save", " save text to audio file",
self.OnSave2Wav),
            MenuParms(204, "&Text", " read text field", self.OnRead),
            MenuParms(205, "&Quit", " Stop Reading", self.OnQuitRead),
            MenuParms(206, "Tts&4", " Sapi 4 test", self.OnTtsRead),
            MenuParms(207, "&Change TTS", " Change-Toggle Sapi 4 to 5",
self.OnTtsFlip),
        ), #END OF VOICE PARMS!
        ), #END OF VOICE MENU!
        ("Settings", (
            MenuParms(302, "&Speaker", " Name for voice", self.OnSettings),
            MenuParms(303, "&Rate", " Rate for voice", self.OnSettings),
            MenuParms(304, "&Pitch", " Pitch for voice", self.OnSettings),
            MenuParms(305, "&Volume", " Volume for voice", self.OnSettings),
        ) #END OF SETTINGS PARMS!
        ) #END OF SETTINGS MENU!
        ) #END OF ITEMS FOR MENU!
        wx.Frame.__init__(self, parent, wx.ID_ANY, title)
        self.control = wx.TextCtrl(self, 1, style=wx.TE_MULTILINE)
        self.control.Bind( wx.EVT_KEY_UP, self.OnKey_Up) #, self.control)
        self.control.Bind( wx.EVT_KEY_DOWN, self.OnKey_Down) #,
self.control)
        self.control.Bind( wx.EVT_CHAR, self.OnKey) #, self.control)
        self.CreateStatusBar() #A Statusbar in the bottom of the window
        #Setting up the menubar.
        self.menuBar = wx.MenuBar()
        self.menuItems = wx.Menu()
        for menuname, items in self.items4menu:
            menu = wx.Menu()
            for o in items:
                menu.Append( o.id4item, o.hk4item, o.khlp4item)
                self.menuItems.Append( o.id4item, o.hk4item, o.khlp4item)
                menu.AppendSeparator()
                wx.EVT_MENU(self, o.id4item, o.handler4item)
                wx.EVT_MENU_HIGHLIGHT(self, o.id4item, self.OnMenu)
            if menuname == "Settings":
                menu.Bind( wx.EVT_CHAR, self.OnKey) #, menu)
            self.menuBar.Append( menu, menuname)
        # Adding the MenuBar to the Frame content.
        self.SetMenuBar( self.menuBar)
        # Use some sizers to see layout options
        self.sizer=wx.BoxSizer(wx.VERTICAL)
        self.sizer.Add(self.control,1,wx.EXPAND)
        #Layout sizers
        self.SetSizer(self.sizer)
        self.SetAutoLayout(1)
        self.sizer.Fit(self)
        self.Show(1)
#TEXT CONTROL KEYS!
    def OnMenu(self, event):
        event.Skip()
        id4btn = event.GetId()
        label4btn = self.menuItems.GetLabelText( id4btn)
        TTS2[ self.ttsp].Speak( label4btn)
    def OnKey(self, event):
        "KEY CAPTURE FOR EDITING! MUST USE EVT_CHAR FOR ALL CODES."
        event.Skip()
        k = event.GetKeyCode()
        m = event.GetModifiers()
#comment rk = event.GetRawKeyCode() #not in all platforms
#comment uk = event.GetUnicodeKey() #Not on platforms that unicode
was not installed!#comment
        ch=""
        if k<256:
            self.sayCap( chr(k))
#CHECK FOR BACK SPACE DELETE!
    def OnKey_Down(self, e):
        "CAPTURE KEY BEING DELETED BEHIND PRESENT POSITION!"
        e.Skip()
        k = e.GetKeyCode()
        m = e.GetModifiers()
        c = self.control.GetInsertionPoint() #present line column position
when event fired!
        if c>0 and k == wx.WXK_BACK:
            col, line = self.control.PositionToXY( c)
            col-=1
            if col<0:
                line-=1
                col = self.control.GetLineLength( line) #length of line
specified!
            c = self.control.XYToPosition( col, line)
            ch = self.control.GetRange( c,c+1)
            pt = self.tts.getPitch()
            self.tts.setPitch( pt -30)
            rt = self.tts.getRate()
            self.tts.setRate( rt -10)
            if ch:
                if ord(ch)==10: ch="Return"
                elif ord(ch)==wx.WXK_SPACE: ch="space"
            TTS2[ self.ttsp].Speak( ch, purge, punc)
            self.tts.setPitch( pt)
            self.tts.setRate( rt)
#KEY UP OR KEY RELEASED!
    def OnKey_Up(self, event):
        "SAY CHAR OR LINE ON WHEN KEY RELEASED!"
        event.Skip()
        k = event.GetKeyCode()
        m = event.GetModifiers()
        c = self.control.GetInsertionPoint() #present line column position
when event fired!
        tl = self.control.GetLastPosition() #last point in textctrl
        colmax, linemax = self.control.PositionToXY( tl)
        col, line = self.control.PositionToXY( c)
        lx = self.control.GetLineLength( line) #length of line specified!
#comment c = self.control.XYToPosition( col, line) #CURSOR POSITION!
        cs = self.control.XYToPosition( 0, line) #LINE START!
        ce = self.control.XYToPosition( lx, line) #LINE END!
        ch = self.control.GetRange( c,c+1)
        if ch:
            if ord(ch)==10: ch="Return"
            elif ord(ch)==wx.WXK_SPACE: ch="space"
        elif c==tl and k in [wx.WXK_RIGHT, wx.WXK_END]: ch="end of text"
        if c<tl and event.ControlDown() and k in [wx.WXK_LEFT,
wx.WXK_RIGHT]:
            for i in range(c+1, c+lx-col):
                ch2 = self.control.GetRange( i,i+1)
                if ch2=="" or ch2 in "!@ #$%^&*(){}_.,;:": break
                else: ch+=ch2
        if k in [wx.WXK_UP, wx.WXK_DOWN, wx.WXK_PAGEUP, wx.WXK_PAGEDOWN]: ch
= self.control.GetRange( cs,ce)
        if k in [wx.WXK_INSERT, wx.WXK_DELETE, wx.WXK_HOME, wx.WXK_END,
wx.WXK_LEFT, wx.WXK_RIGHT, wx.WXK_UP, wx.WXK_DOWN, wx.WXK_PAGEUP,
wx.WXK_PAGEDOWN]:
            if c==0 and (k==wx.WXK_HOME or not event.ControlDown() and
k==wx.WXK_LEFT): ch = " Start Of Text "+ch
            self.sayCap( ch) #self.tts.Speak( " %s " % ch, async, punc,
purge)
#SAY CAPITALS IN HIGHER PITCH!
    def sayCap(self, ch):
        "CHANGE PITCH AND RATE IF AN ALPHA SINGLE CHAR!"
        if len(ch)==1 and ch.isalpha() and ch.isupper():
            pt = self.tts.getPitch()
            self.tts.setPitch( pt+30)
            rt = self.tts.getRate()
            self.tts.setRate( rt+30)
        if len(ch)==1 and ord(ch)<128:
            if ord( ch)==13: ch="Return"
            elif ord( ch)==10: ch="Line Feed"
            elif ord( ch)==32: ch="space"
        self.tts.Speak( " %s " % ch, async, purge, punc)
        if len(ch)==1 and ch.isalpha() and ch.isupper():
            self.tts.setPitch( pt)
            self.tts.setRate( rt)
# VOICE SETTINGS!
    def OnSettings(self, e):
        "SETTINGS MENU BUTTONS, WHEN ENTERING SAY LABEL OF BUTTON!"
        eventType = e.GetEventType()
        eventName = e.GetClassName()
        self.menuId = e.GetId()
# TTS2[ self.ttsp].Speak( self.menuId)
        btn = e.GetEventObject()
        label4btn = self.menuItems.GetLabelText( self.menuId)
#NOTE: THE SELF MUST BE USED FOR ANY BTN ITEM IN ORDER TO BE SEEN. ADDED
SELF.FILEMENU INSTEAD OF FILEMENU
# label4btn = btn.filemenu.GetLabelText( 102) #SAYS OPEN!
        set_value = " Error In Label!"
        min = 0
        max = 100
        steps = 10
        tics = 5
        if label4btn == "Speaker":
            present = TTS2[ self.ttsp].getVoiceNum()
            set_value = TTS2[ self.ttsp].getVoiceName()
            max = TTS2[ self.ttsp].getVoiceCount()-1
            if self.ttsp==4: min = 1; max+=1
            steps = 1
            tics = 1
        elif label4btn == "Rate":
            present = TTS2[ self.ttsp].getRate()
            set_value = str( present) +"%"
        elif label4btn == "Pitch":
            present = TTS2[ self.ttsp].getPitch()
            set_value = str( present) +"%"
        elif label4btn == "Volume":
            present = TTS2[ self.ttsp].getVolume()
            set_value = str( present) +"%"
        TTS2[ self.ttsp].Speak( " %s %s" % (label4btn, set_value), async,
purge)
#SET UP SPIN CTRL FOR THE SETTING SELECTED!!
        self.sldr_ctrl = wx.Slider(
            self, 999, present, min, max, (-1, -1), (-1, -1),
            wx.SL_AUTOTICKS|wx.SL_HORIZONTAL|wx.SL_LABELS|wx.SL_INVERSE
            ) #END OF CTRL DEFINITION!
        self.sldr_ctrl.Bind( wx.EVT_SLIDER, self.SetVoice, self.sldr_ctrl)
        self.sldr_ctrl.Bind( wx.EVT_KEY_UP, self.KillSlider, self.sldr_ctrl)
        self.sldr_ctrl.SetFocus()
    def KillSlider(self, e):
        "KILL THE SPIN CONTROL IF ENTER KEY PRESSED!"
        k = e.GetKeyCode()
        if k == wx.WXK_RETURN:
            TTS2[ self.ttsp].Speak(" %s Set " %
self.menuItems.GetLabelText( self.menuId))
            self.Do_Edit( e)
    def SetVoice(self,e):
        "SET VOICE PARAMETER ADJUSTED!"
        btn = e.GetEventObject()
        spin_Id = e.GetId()
        value = self.sldr_ctrl.GetValue()
        max = self.sldr_ctrl.GetMax()
        min = self.sldr_ctrl.GetMin()
        label4btn = self.menuItems.GetLabelText( self.menuId)
        TTS2[ self.ttsp].Speak( " %s %s" % (label4btn, str(value)), async,
purge)
        if label4btn == "Speaker":
            rt = TTS2[ self.ttsp].getRate()
            pt = TTS2[ self.ttsp].getPitch()
            TTS2[ self.ttsp].setVoice( value)
            if self.ttsp==TS5:
                TTS2[ self.ttsp].setRate( rt)
                TTS2[ self.ttsp].setPitch( pt)
            set_value = TTS2[ self.ttsp].getVoiceName()
        elif label4btn == "Rate":
            TTS2[ self.ttsp].setRate( value)
            set_value = str( value)+"%"
        elif label4btn == "Pitch":
            TTS2[ self.ttsp].setPitch( value)
            set_value = str( value)+"%"
        elif label4btn == "Volume":
            if value < min+5:
                TTS2[ self.ttsp].setVolume( 50)
                TTS2[ self.ttsp].Speak( "Volume Minimum!")
                value = 0
            TTS2[ self.ttsp].setVolume( value)
            set_value = str( value)+"%"
        TTS2[ self.ttsp].Speak(" %s %s" % (label4btn, set_value), async,
purge)
    def OnAbout(self,e):
        "A dialog box saying what the editor is about!"
        text = " A sample editor with voice \n in wxPython."
        self.tts.Speak( "About A Sample Editor!"+text)
        d= wx.MessageDialog( self, text, "About Sample Editor", wx.OK)
                            # Create a message dialog box
        d.ShowModal() # Shows it
        d.Destroy() # finally destroy it when finished.
    def OnExit(self,e):
        self.Close(True) # Close the frame.
    def OnOpen(self,e):
        """ Open a file"""
        self.setFilePath( "o")
        f=open(os.path.join(self.dirname, self.filename),'r')
        self.control.SetValue(f.read())
        f.close()
    def OnSave(self,e):
        """ Save a file"""
        self.setFilePath( "s")
        f=open(os.path.join(self.dirname, self.filename),'w')
# self.control.SetValue(f.read())
        f.write( self.control.GetValue())
        f.close()
    def setFilePath(self, type4file=""):
        " Search directory for path and file name!"
        fn=self.filename
        t4f = wx.OPEN
        if type4file[0] in "sS":
            t4f = wx.SAVE|wx.FD_OVERWRITE_PROMPT
# fn = self.filename
        dlg = wx.FileDialog(self, self.filename +" or Choose a file",
self.dirname, fn, "*.*", t4f)
        if dlg.ShowModal() == wx.ID_OK:
            self.filename = dlg.GetFilename()
            self.dirname = dlg.GetDirectory()
        dlg.Destroy()
    def OnWav2Read(self,e):
        """ Open a file to read"""
        self.setFilePath( "o")
        self.tts.SpeakFromWav( os.path.join(self.dirname, self.filename),
async, purge)
    def OnSave2Wav(self,e):
        """ Save text to a wav file"""
        self.setFilePath( "s")
        self.tts.SpeakToWav( os.path.join(self.dirname, self.filename),
self.control.GetValue())
    def OnRead(self,e):
        """ Read the text"""
        self.tts.Speak( self.control.GetValue(), async, purge)
    def OnQuitRead(self,e):
        """ Quit the reading of the text"""
        self.tts.Speak( " Talking Stopped!", purge)
    def OnTtsRead(self,e):
        """SAPI 4 TEST!"""
        tts4.Speak( " Sapi %d, %s Talking!" % (tts4.getVoiceNum(),
tts4.getVoiceName()))
        tts4.setVoiceByName( "Sandy")
        tts4.Speak( " Number of Sapi 4 voices: %d!" % tts4.getVoiceCount())
    def OnTtsFlip(self,e):
        """ FLIP THE TTS ENGINE FOR SETTING ADJUSTMENTS!"""
        if self.ttsp==TS4:
            self.ttsp=TS5
            txt="Sapi 5 Now!"
        else:
            self.ttsp=TS4
            txt="Sapi 4 Now!"
        #TTS2[ self.ttsp].Speak( txt)
        self.tts = TTS2[ self.ttsp] #.Speak( txt)
        self.tts.Speak( txt)
    def Do_Edit(self,e):
        """ Edit the file"""
        if self.sldr_ctrl:
            self.sldr_ctrl.Destroy()
        self.control.SetFocus()
app = wx.PySimpleApp()
frame = MainWindow(None, -1, "Voice Editor")
app.MainLoop()

FT wrote:

    The menu text is the HotKey text and there is a built in function for
that as you will see when you go down to the OnMenu handler Call.

#LAST MODIFIED SUNDAY, AUGUST 10 2008
#ADDED MENUITEMS LIST FOR ID SEARCH.
#MODIFIED WEDNESDAY, JULY 23 2008
#CREATED TUPLES FOR ALL MENU ITEMS!
#ADDED MENUBAR_SETTINGS TO FIND SETTINGS PARMS.
#MODIFIED TUESDAY, JULY 22 2008
#ADDED OR WENT BACK TO SLIDER CONTROL FOR BETTER MOVEMENT USING PAGE UP AND
DOWN!
#ERASE ALL MAX AND MIN CHECKS INSIDE FUNCTION SETVOICE!
#MODIFIED MONDAY, JULY 21 2008
#ADDED SPIN CONTROL FOR VOICE SETTINGS!
#ADDED KEY EVENT FOR SPIN CONTROL SO ENTER KEY EXITS AND KILLS SPIN!
#MODIFIED THURSDAY, JULY 17 2008
#ADDED TTS2 A DICTIONARY OF VOICES TO CONTROL ANY TYPE OF VOICE, SAPI 4 OR
SAPI 5
#ADDED TTSP POINTER TO WHICH VOICE TO USE!
#ADDED CHANGE VOICE TOGGLE FUNCTION AND VOICE MENU ITEM FOR THE VOICE
CHANGE!
#MODIFIED TUESDAY, JULY 15 2008
#ADDED THE SAPI 4 ENGINE FOR EXTRA VOICES.
desc="""In the following example we use a sizer with vertical layout"""
#Editor.py
import wx
import os
  
Dude, you really need to take a few minutes to establish a source code control system. It is absolutely trivial to set up a CVS repository on your local computer, and then this modification history becomes part of the repository, instead of part of the source code. In addition, you can go back check out a version of your project exactly as it was on, say, July 15, without interfering with the master copy.

···

--
Tim Roberts, timr@probo.com
Providenza & Boekelheide, Inc.