Binding dynamically to any arbitrary event

24 views
Skip to first unread message

Quentin Cosendey

unread,
Jul 13, 2022, 11:45:00 AM7/13/22
to wx-u...@googlegroups.com
Hello,

I'm adding scripting capabilities in one of my apps, and I would like to
give the possibility for scripters to bind to any arbitrary event.

Basically I want the following function to be callable from a script (I
have removed all script-to-C protocol details / boilerplate code that
are unneeded here)

static void Bind (wxEvtHandler& handler, wxEventType eventType, const
std::function<void(wxEvent&)>& func) {
  handler.Bind(eventType, func);
}

However, this doesn't compile.

If I replace eventType by a precise event type, such as wxEVT_LEFT_DOWN,
wxEVT_MENU, wxEVT_BUTTON, etc. then it works. But it means that I have
to make a fonction for each of the different events I want to allow from
the script. That's not very convenient.

Why can't I do that ?
Is it possible to do what I want ? How ?

Here are the errors given by MinGW-W64:

In file included from
C:/mingw-w64/i686-8.1.0-posix-dwarf-rt_v6-rev0/mingw32/i686-w64-mingw32/include/wx/wx.h:24,
...
C:/mingw-w64/i686-8.1.0-posix-dwarf-rt_v6-rev0/mingw32/i686-w64-mingw32/include/wx/event.h:
In instantiation of 'class wxEventFunctorFunctor<int,
std::function<void(wxEvent&)> >':
C:/mingw-w64/i686-8.1.0-posix-dwarf-rt_v6-rev0/mingw32/i686-w64-mingw32/include/wx/event.h:3887:9:
required from 'void wxEvtHandler::Bind(const EventTag&, const Functor&,
int, int, wxObject*) [with EventTag = int; Functor =
std::function<void(wxEvent&)>]'
...
C:/mingw-w64/i686-8.1.0-posix-dwarf-rt_v6-rev0/mingw32/i686-w64-mingw32/include/wx/event.h:532:43:
error: 'int' is not a class, struct, or union type
     typedef typename EventTag::EventClass EventArg;


     Thank you very much for your answers.


Igor Korot

unread,
Jul 13, 2022, 12:13:27 PM7/13/22
to wx-u...@googlegroups.com
Hi,

On Wed, Jul 13, 2022 at 10:44 AM Quentin Cosendey
<quentin....@bluewin.ch> wrote:
>
> Hello,
>
> I'm adding scripting capabilities in one of my apps, and I would like to
> give the possibility for scripters to bind to any arbitrary event.

Why do you want that?

Imagine a situation where you have an "arbitrary" event of list item selection.
And you want to bind it to the button?

How will this work?

Thank you.
> --
> Please read https://www.wxwidgets.org/support/mlhowto.htm before posting.
> ---
> You received this message because you are subscribed to the Google Groups "wx-users" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to wx-users+u...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/wx-users/0a4cdeb3-6c04-0a8a-4cb0-3bbc059b1f69%40bluewin.ch.

Vadim Zeitlin

unread,
Jul 13, 2022, 12:34:50 PM7/13/22
to wx-u...@googlegroups.com
On Wed, 13 Jul 2022 17:44:58 +0200 Quentin Cosendey wrote:

QC> I'm adding scripting capabilities in one of my apps, and I would like to
QC> give the possibility for scripters to bind to any arbitrary event.

But what will they do with the event once they get it? They'd need to know
its concrete type to retrieve the information from it and this depends on
the event type.

QC> Basically I want the following function to be callable from a script (I
QC> have removed all script-to-C protocol details / boilerplate code that
QC> are unneeded here)
QC>
QC> static void Bind (wxEvtHandler& handler, wxEventType eventType, const
QC> std::function<void(wxEvent&)>& func) {
QC>   handler.Bind(eventType, func);
QC> }
QC>
QC> However, this doesn't compile.

Yes, Bind() requires using the callback type compatible with the event
type and checks for it at compile-time. This can't be done if the event
type is specified during run-time.

QC> Why can't I do that ?

The above should answer this question.

QC> Is it possible to do what I want ? How ?

The simplest is to override ProcessEvent() and dispatch your events
yourself from there, bypassing wx event entirely.

Regards,
VZ

--
TT-Solutions: wxWidgets consultancy and technical support
http://www.tt-solutions.com/

Quentin Cosendey

unread,
Jul 13, 2022, 1:32:19 PM7/13/22
to wx-u...@googlegroups.com
Hello,


VZ>  But what will they do with the event once they get it? They'd need
to know its concrete type to retrieve the information from it and this
depends on the event type.


The scripting language is lua, so it isn't strongly typed.


In the event function, my idea is to use typeid to get the actual type
of the event and pass a correctly stuffed reference on the script side.


VZ>  Yes, Bind() requires using the callback type compatible with the
event type and checks for it at compile-time. This can't be done if the
event type is specified during run-time.


OK, that's what I thought, thank you for confirming it


VZ>  The simplest is to override ProcessEvent() and dispatch your events
yourself from there, bypassing wx event entirely.


Well... it looks complicated if I need to completely bypass everything.
Sad that there is nothing simpler.

I just wanted to reuse what already exists.


In this case it's just simpler to make as many functions as there are
different event types to handle.



Igor> Imagine a situation where you have an "arbitrary" event of list
item selection. And you want to bind it to the button?


Anyway it won't work in this case, since the list will obviously never
generate a button event.

But the scripters are normally not stupid. They can still perfectly do
it though.



Thank you for your answers.

Vadim Zeitlin

unread,
Jul 13, 2022, 1:49:33 PM7/13/22
to wx-u...@googlegroups.com
On Wed, 13 Jul 2022 19:32:19 +0200 Quentin Cosendey wrote:

QC> Well... it looks complicated if I need to completely bypass everything.

I don't understand why do you think it's complicated, but if you really
want to use something like Bind() but not type-safe, you could use
Connect().

Igor Korot

unread,
Jul 13, 2022, 2:06:26 PM7/13/22
to wx-u...@googlegroups.com
Hi,
True..
But if API allows, why not try it.

Besides - it looks like you want to disregard that
and pretend that it will occur.

Thank you.
> --
> Please read https://www.wxwidgets.org/support/mlhowto.htm before posting.
> ---
> You received this message because you are subscribed to the Google Groups "wx-users" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to wx-users+u...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/wx-users/357bf2d2-97c6-2ba7-1f00-33e8a092d631%40bluewin.ch.

Gunter Königsmann

unread,
Jul 13, 2022, 4:16:01 PM7/13/22
to wx-u...@googlegroups.com, Quentin Cosendey
The problem is that each event type can transport different data: A mouse position. A position on the keyboed. An Unicode character. An event number. A boolean that tells if the item is checked. If your script only is informed about the fact that any event has occurred and doesn't get to know what kind of event this was it gets events all the time (idle events, mouse movement events, mouse enter and exit events, keyboard focus events, ui redraw events, key up or down events, Power Management Events,...). So basically you get flooded by events but only get the information that something has happened without details about what has actually happened. Not very useful, that.

If your script gets the information that something has happened and the raw data the event comes with, but not the event type there is no way of telling what the data actually means. Therefore the script still gets flooded by events without knowing what they mean and which ones are important.

And if your script on each event gets the event type and the data it needs to handle the data for every event type differently. This means you end up with basically binding each possible event type to a separate function that handles it. This can easily be done using bind.

gunter.ko...@gmail.com

unread,
Jul 13, 2022, 4:27:20 PM7/13/22
to wx-users
My guess is what you really want to do is to derive your own class from wxButton that automatically binds the one or two events that are of interest for your script to handler functions that cause your program to call the right script callbacks with the right parameters. Then you derive your own function from wxTextBox that forwards the info that someone has changed the text, perhaps  the info that someone has pressed a key and possibly also the info that the mouse focus has left this textbox (which means the user has most probably finished changing the text) to your scripting engine. Then you repeat that approach with all classes you want to use in the script-connected part of the GUI and use these classes instead of the plain wxWidgets ones. My guess is (but it''s only a guess) you end up calling completely different types of callback if a button is pressed, if the content of a textbox changes or if a radio button is checked.

Quentin Cosendey

unread,
Jul 19, 2022, 3:59:38 PM7/19/22
to wx-u...@googlegroups.com
Hello,


VZ>  I don't understand why do you think it's complicated, but if you
really want to use something like Bind() but not type-safe, you could
use Connect().


I finally understood how to use Connect, and in fact it works perfectly
for my case.


Thank you.


All the best.
Reply all
Reply to author
Forward
0 new messages