wxpython postevent from coroutine to a parent window (modal)

Viewed 33

I got a coroutine running to catch events sent by a footswitch device. This coroutine is launched from the main window as following.

class FootswitchMonitor(wx.Frame):

    def __init__(self, parent, title):
        super().__init__(parent, title=title,
                         size=(350, 150))
        self.InitUI()
        StartCoroutine(self.footswitch_callback, self)
        self.Bind(EVT_FOOTSWITCH, self.pedal)

    def on_footswitch(self, evt):
        print(f"eid: {evt.GetId()} code: {evt.code} ")

    async def footswitch_callback(self):
        device = get_footswitch_device()
        device.grab()
        key_pressed = None
        async for ev in device.async_read_loop():
            if ev.type == 1 and ev.value == 1: # only key events and key_down
                if key_pressed != ev.code:
                    event = footswitch_event(code=ev.code)
                    wx.PostEvent(self, event)
                    key_pressed = ev.code
            else:
                key_pressed = None

    def setup_footswitch(self, event):
        cDialog = ConfigDialog(None)
        cDialog.ShowModal()
        cDialog.Destroy()

In order to setup the device I use a ConfigDialog dialog box where I'd like to bind the same EVT_FOOTSWITCH.

class ConfigDialog(wx.Dialog):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.InitUI()
        self.SetSize(350, 450)
        self.SetTitle("Configuration")
        self.Bind(EVT_FOOTSWITCH, self.footswitch_setup_callback)

And this is where it hurts. The main coroutine has FootswitchMonitor frame as target: wx.PostEvent(self, event). So the ConfigDialog windows won't get it.

I cannot run another coroutine with this device in the parent windows because it is grabed, which is locked by the main coroutine.

So my question is how can I catch the EVT_FOOTSWITCH in ConfigDialog a parent windows. Is it possible to post the event globaly? Is it possible to stop the main coroutine to run anotheone in the modal window?

1 Answers

I have something similar where I run reading the footpedal in a separate thread. If the user wishes to reconfigure the pedal settings, I simply stop the thread, for the duration of the reconfiguration, then restart it.
Stopping the thread also ungrabs the device.
I do insist the program is restarted, as I only read the configuration of the footpedal's settings at program start. I found it less complicated this way.

Your other option, if you wish to attack it from a different angle, is to Unbind the event i.e. self.Unbind(EVT_FOOTSWITCH) and ungrab the device.
Then Bind it to your reconfiguration routine, which Unbind's when it finishes and finally rebind the event back to the original, whilst regrabbing the device, when you return to the main app.

My rather vast code can be perused at https://sourceforge.net/projects/footswitch2 , if you need further clues.
When browsing the file fs2.py search for PedalThread

Related