Posting event from inside of another handler

I’m trying to fire an event from inside of another event. I’ve grabbed a demo to illustrate and added an additional event and handler. The add is the DNPCompare

#!/usr/bin/env python3
# -*- coding: UTF-8 -*-

import wx
import time
import threading

import wx.lib.newevent as ne

MooEvent, EVT_MOO = ne.NewEvent()
GooEvent, EVT_GOO = ne.NewCommandEvent()

DELAY = 0.7

def evt_thr(win):
    wx.PostEvent(win, MooEvent(moo=1))

def cmd_thr(win, id):
    wx.PostEvent(win, GooEvent(id, goo=id))

ID_CMD1 = wx.NewIdRef()
ID_CMD2 = wx.NewIdRef()

DNPCompare, EVT_DNP_COMPARE = wx.lib.newevent.NewEvent()
ID_DNPCompare = wx.NewIdRef()

class Frame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, -1, "MOO")
        sizer = wx.BoxSizer(wx.VERTICAL)

        self.Bind(EVT_MOO, self.on_moo)
        b = wx.Button(self, -1, "Generate MOO")
        sizer.Add(b, 1, wx.EXPAND)
        b.Bind(wx.EVT_BUTTON, self.on_evt_click)

        b = wx.Button(self, ID_CMD1, "Generate GOO with %d" % ID_CMD1)
        sizer.Add(b, 1, wx.EXPAND)
        b.Bind(wx.EVT_BUTTON, self.on_cmd_click)

        b = wx.Button(self, ID_CMD2, "Generate GOO with %d" % ID_CMD2)
        sizer.Add(b, 1, wx.EXPAND)
        b.Bind(wx.EVT_BUTTON, self.on_cmd_click)

        b = wx.Button(self, ID_DNPCompare, f'Generate Compare with {ID_DNPCompare}')
        sizer.Add(b, 1, wx.EXPAND)
        b.Bind(wx.EVT_BUTTON, self.on_compare)

        self.Bind(EVT_GOO, self.on_cmd1, id=ID_CMD1)
        self.Bind(EVT_GOO, self.on_cmd2, id=ID_CMD2)
        self.Bind(EVT_DNP_COMPARE, self.on_compare, id=ID_DNPCompare)


    def on_evt_click(self, e):
        t = threading.Thread(target=evt_thr, args=(self, ))

    def on_cmd_click(self, e):
        t = threading.Thread(target=cmd_thr, args=(self, e.GetId()))

    def on_compare(self, e):
        """ our compare instruction

        :param e:
        """'compare = {e}', 'Got Compare')

    def show(self, msg, title):
        dlg = wx.MessageDialog(self, msg, title, wx.OK)

    def on_moo(self, e):"MOO = %s" % e.moo, "Got Moo")

    def on_cmd1(self, e):"goo = %s" %, "Got Goo (cmd1)")

    def on_cmd2(self, e):"goo = %s" %, "Got Goo (cmd2)")
        new_event = DNPCompare(id=ID_DNPCompare, left=1, right=2)
        wx.QueueEvent(self, new_event)

class MyApp(wx.App):
    def OnInit(self):
        self.frame = Frame()
        return True

if __name__ == "__main__":
    app = MyApp(0)

If I use the button to generate the EVT_DNP_COMPARE event the on_compare handler is called. But if i try and post the event from inside of on_cmd2, on_compare is not accessed. I also tried generating the event through PostEvent with the same result, no event ever distributed to on_compare.

What do i need to do differently?

Hi cryptoref,

First, I tried your code and checked the problem by changing as

-       wx.QueueEvent(self, new_event)
+       print(self.ProcessEvent(new_event))

It always returns False, which may mean that there are no handlers.
The document of ProcessEvent (wxWidgets: wxEvtHandler Class Reference) says

true if a suitable event handler function was found and executed, and the function did not call wxEvent::Skip.

Finally, I found that the handler of wx.EVT_BUTTON can receive a CommandEvent not an Event.
To fix the problem, try this

- DNPCompare, EVT_DNP_COMPARE = wx.lib.newevent.NewEvent()
+ DNPCompare, EVT_DNP_COMPARE = wx.lib.newevent.NewCommandEvent()

I wanted to link the documentation for wx.ProcessEvent, but the first hit of google
[wx.ProcessEvent — wxPython Phoenix 4.1.2a1 documentation] is NotFound. :worried: Does anyone know where it has gone?

1 Like

Thanks so much. Knew it was something simple, but embarrassed it was that much of a fat finger. Thanks again.