Programmatically Raising an Event

I am trying to write a function that will programmatically raise a (non-custom) event, but I can’t figure out how to do it. I’ve posted some sample code below. It is a simple application with a button, and when that button is clicked, it should raise the EVT_TEXT_MAXLEN event. Instead, I’m getting the following error: “TypeError: in method ‘PostEvent’, expected argument 2 of type ‘wxEvent &’”

Can anyone see what I’m doing wrong? Thanks in advance.

···

#-------------------------------------------------------------------------------
import wx

class MainWindow(wx.Frame):
def init(self, parent, id, title):
wx.Frame.init (self, parent, -1, title, size=(500,300))
self.panel = wx.Panel(self, -1)

    self.button = wx.Button(self.panel, -1, label="&Click me!")

    box = wx.BoxSizer(wx.VERTICAL)
    box.Add(self.button)
    self.panel.SetSizer(box)

    self.button.Bind(wx.EVT_BUTTON, self.OnButtonClick)
    self.button.Bind(wx.EVT_TEXT_MAXLEN, self.OnButtonMaxLength)

    self.Centre()
    self.Show(True)

def OnButtonClick(self, event):
    print "Inside OnButtonClick()"
    evt = wx.EVT_TEXT_MAXLEN
    wx.PostEvent(self.button, evt)

def OnButtonMaxLength(self, event):
    print "Inside OnButtonMaxLength()"

if name == “main”:
app = wx.App(redirect=False)
frame = MainWindow(None, -1, “Application Title”)

app.MainLoop()

...

Can anyone see what I'm doing wrong? Thanks in advance.

You need an event object, not an event ID.

Here is code that I use successfully:

class CharacterEvent(wx.PyEvent):
   """
      Simple event to carry a character.
   """

   event_type = wx.NewId()

   def __init__(self, character):
      wx.PyEvent.__init__(self, eventType=self.event_type)
      self.character = character

...
class ShellPanel(wx.Panel):
...
      self.Connect(-1, -1, CharacterEvent.event_type, self.on_character)
...
            wx.PostEvent(self, CharacterEvent(output))

Cheers, Carsten.

···

On Sat, 2009-03-07 at 18:23 -0500, mercado wrote:

Thanks for the response Carsten. It definitely pointed me in the right direction.

However, I’m looking to raise a wx defined event type, not create a custom event type of my own. After a little bit more fiddling around, this is what I came up with. It seems to do what do what I want.

···

On Sun, Mar 8, 2009 at 7:02 AM, Carsten Koch CarstenKochICEM@web.de wrote:

You need an event object, not an event ID.


import wx

class MainWindow(wx.Frame):
def init(self, parent, id, title):
wx.Frame.init (self, parent, -1, title, size=(500,300))

    self.panel = wx.Panel(self, -1)
   
    self.text = wx.TextCtrl(self.panel, -1,
                       value="",
                       size=(400, -1)
                       )

    self.button = wx.Button(self.panel, -1, label="&Click me!")

    self.text.SetMaxLength(3)

    box = wx.BoxSizer(wx.VERTICAL)
    box.Add(self.text)
    box.Add(self.button)

    self.panel.SetSizer(box)

    self.button.Bind(wx.EVT_BUTTON, self.OnButtonClick)
    self.text.Bind(wx.EVT_TEXT_MAXLEN, self.OnButtonMaxLength)

    self.text.SetFocus()
   

    self.Centre()
    self.Show(True)

def OnButtonClick(self, event):
    print "Inside OnButtonClick()"
    evt = wx.CommandEvent()
    evt.SetEventType(wx.EVT_TEXT_MAXLEN.typeId)

    wx.PostEvent(self.text, evt)

def OnButtonMaxLength(self, event):
    print "Inside OnButtonMaxLength()"

if name == “main”:
app = wx.App(redirect=False)

frame = MainWindow(None, -1, "Application Title")

app.MainLoop()

A cheaper way to get the same result could be:


def OnButtonClick(self, event):
print “Inside OnButtonClick()”
self.OnButtonMaxLenght()

def OnMaxLength(self, event = None):

if not event is None: event.Skip()
print “Inside OnMaxLength()”

···

2009/3/8 mercado python.dev.9@gmail.com

On Sun, Mar 8, 2009 at 7:02 AM, Carsten Koch CarstenKochICEM@web.de wrote:

You need an event object, not an event ID.

Thanks for the response Carsten. It definitely pointed me in the right direction.

However, I’m looking to raise a wx defined event type, not create a custom event type of my own. After a little bit more fiddling around, this is what I came up with. It seems to do what do what I want.


import wx

class MainWindow(wx.Frame):
def init(self, parent, id, title):
wx.Frame.init (self, parent, -1, title, size=(500,300))

    self.panel = wx.Panel(self, -1)

self.text = wx.TextCtrl(self.panel, -1,
value=“”,
size=(400, -1)

                       )

    self.button = wx.Button(self.panel, -1, label="&Click me!")

self.text.SetMaxLength(3)

    box = wx.BoxSizer(wx.VERTICAL)

box.Add(self.text)

    box.Add(self.button)

    self.panel.SetSizer(box)

    self.button.Bind(wx.EVT_BUTTON, self.OnButtonClick)

self.text.Bind(wx.EVT_TEXT_MAXLEN, self.OnButtonMaxLength)

    self.text.SetFocus()

   

    self.Centre()
    self.Show(True)

if name == “main”:
app = wx.App(redirect=False)

frame = MainWindow(None, -1, "Application Title")

app.MainLoop()


wxpython-users mailing list

wxpython-users@lists.wxwidgets.org

http://lists.wxwidgets.org/mailman/listinfo/wxpython-users

raffaello wrote:

A cheaper way to get the same result could be:

...
   def OnButtonClick(self, event):
        print "Inside OnButtonClick()"
        self.OnButtonMaxLenght()

    def OnMaxLength(self, event = None):

        if not event is None: event.Skip()
        print "Inside OnMaxLength()"

Just being nitpicky, but I think the following "if" is easier to read:

if event is not None: event.Skip()

···

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

Blog: http://blog.pythonlibrary.org
Python Extension Building Network: http://www.pythonlibrary.org

Yes, you’re right, given the example I posted in my initial message.

It probably would have been more helpful if I had posted an example that was closer to what I was actually trying to achieve. What I was initially trying to do was create a subclass of wx.Notebook that raised the EVT_NOTEBOOK_PAGE_CHANGED event in the ChangeSelection method.

It ended up being surprisingly easy once I figured it out:

···

On Sun, Mar 8, 2009 at 3:48 PM, raffaello barbarossa.platz@gmail.com wrote:

A cheaper way to get the same result could be:

def OnButtonClick(self, event):
print “Inside OnButtonClick()”

self.OnButtonMaxLenght()

def OnMaxLength(self, event = None):

if not event is None: event.Skip()
print “Inside OnMaxLength()”


class Notebook(wx.Notebook):
def ChangeSelection(self, page):

    wx.Notebook.ChangeSelection(self, page)

    e = wx.NotebookEvent()
    e.SetEventType(wx.EVT_NOTEBOOK_PAGE_CHANGED.typeId)
    e.SetSelection(page)
    wx.PostEvent(self, e)

Does anybody know why the wx.Notebook.ChangeSelection method doesn’t raise the EVT_NOTEBOOK_PAGE_CHANGED method? This seems really strange to me. The documentation indicates that ChangeSelection doesn’t raise the event, but doesn’t give any justification why.

http://docs.wxwidgets.org/stable/wx_wxnotebook.html#wxnotebookchangeselection

True, Mike, my problem is that I don’t think in English :slight_smile:

···

2009/3/9 Mike Driscoll mike@pythonlibrary.org

raffaello wrote:

A cheaper way to get the same result could be:

def OnButtonClick(self, event):

    print "Inside OnButtonClick()"

    self.OnButtonMaxLenght()



def OnMaxLength(self, event = None):



    if not event is None: event.Skip()

    print "Inside OnMaxLength()"

Just being nitpicky, but I think the following “if” is easier to read:

if event is not None: event.Skip()


Mike Driscoll

Blog: http://blog.pythonlibrary.org

Python Extension Building Network: http://www.pythonlibrary.org


wxpython-users mailing list

wxpython-users@lists.wxwidgets.org

http://lists.wxwidgets.org/mailman/listinfo/wxpython-users

mercado wrote:

Does anybody know why the wx.Notebook.ChangeSelection method doesn't raise the EVT_NOTEBOOK_PAGE_CHANGED method? This seems really strange to me. The documentation indicates that ChangeSelection doesn't raise the event, but doesn't give any justification why.

Because the policy is that calling a method to do something does not generate the events that would be done if the user does the same thing. The exception to the rule is that if the method was already generating the event at the time that the policy was adopted then it will continue to do so.

Several months ago one of the developers went through the code and added a bunch of ChangeFoo methods that don't generate an event to go along with some of the legacy SetFoo methods that already exist and do generate the event. In other words, if you call the notebook's SetSelection instead of ChangeSelection then you should be getting an event.

···

--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!