Discussion:
Signal Slot Mechanism
Max
21 years ago
Permalink
Hello,

This is my first post to the mailing so, first of all, hello to everybody.

I have started evaluating wx windows against Qt. Although I am happy
with Qt, from the point of the price, I would prefer to use wx windows.

One of my primary questions is the lack of signal slot mechanism in wx.
I have used this mechanism in my previous Qt applications extensively
and I believe it is really a significant improvement to code robustness
and clarity. I have used signal and slots primarily to connect my GUI
widgets to non gui storage classes ( such as an elements of a CAD model,
preferences, etc. )

I would like to check if anyone has used libsigc++ (
http://libsigc.sourceforge.net/ ) with wx widgets. I could imagine this
could be possible with multiple inheritance. I guess it could look like :

class MyApp : public wxApp, public SigC::Object
{
...
}

I would appreciate if any wx expert can elaborate on this issue.

Thanks in advance,

Max.
Vadim Zeitlin
21 years ago
Permalink
On Wed, 05 May 2004 10:03:11 +0200 Max <***@machsim.com> wrote:

M> One of my primary questions is the lack of signal slot mechanism in wx.

This is as fair as saying "lack of any way to write Qt programs in
standard C++". wxWindows != Qt and they use different approaches, it is not
"lack" in any reasonable sense of the word.

M> I have used this mechanism in my previous Qt applications extensively
M> and I believe it is really a significant improvement to code robustness
M> and clarity.

Maybe, but it's not C++. wxWindows has wxEvtHandler class and Connect()
method to do something similar (but less flexibly).

M> I would like to check if anyone has used libsigc++ (
M> http://libsigc.sourceforge.net/ ) with wx widgets.

I didn't use it but I think it should be possible -- provided you have a
decent compiler.

Otherwise we really should enhance wxWindows to do at least some of the
things that libsigc does. It is on my (and probably others...) TODO list
for quite some time but we never found time to do it. At the very least
Connect() should be made type safe...

Regards,
VZ
Max
21 years ago
Permalink
Post by Vadim Zeitlin
M> One of my primary questions is the lack of signal slot mechanism in wx.
This is as fair as saying "lack of any way to write Qt programs in
standard C++". wxWindows != Qt and they use different approaches, it is not
"lack" in any reasonable sense of the word.
Sorry, if my wording sounds harsh, I didn't mean to.

I am very much aware that wxWindows != Qt and you shall have also
noticed that I am trying to find a way to bring the signal-slot comfort
to a wx application. I am not really trying to make a comparision, but
rather checking if I would be able to use the practices which I have
developed and successfully deployed so far.
Post by Vadim Zeitlin
M> I have used this mechanism in my previous Qt applications extensively
M> and I believe it is really a significant improvement to code robustness
M> and clarity.
Maybe, but it's not C++. wxWindows has wxEvtHandler class and Connect()
method to do something similar (but less flexibly).
Qt's signal slot implementation isn't C++. But libsigc++ is.
Post by Vadim Zeitlin
M> I would like to check if anyone has used libsigc++ (
M> http://libsigc.sourceforge.net/ ) with wx widgets.
I didn't use it but I think it should be possible -- provided you have a
decent compiler.
The problems could originate from the fact that the ligsigc++ relies on
C++ templates. This is actually the point which I am curious.

Regards,

Max.
Post by Vadim Zeitlin
Otherwise we really should enhance wxWindows to do at least some of the
things that libsigc does. It is on my (and probably others...) TODO list
for quite some time but we never found time to do it. At the very least
Connect() should be made type safe...
Regards,
VZ
---------------------------------------------------------------------
Vadim Zeitlin
21 years ago
Permalink
On Wed, 05 May 2004 12:08:25 +0200 Max <***@machsim.com> wrote:

M> Qt's signal slot implementation isn't C++. But libsigc++ is.

Yes, this is why we might use libsigc++. But it could be an overkill for
us too and, besides, integrating another big library is not that easy. We
might just take some ideas from it and implement it ourselves instead.

M> The problems could originate from the fact that the ligsigc++ relies on
M> C++ templates. This is actually the point which I am curious.

As I said, if you have a "decent" compiler (e.g. gcc 3.2+, VC7.1) this
should work. It definitely will *not* work with *all* compilers supported
by wxWindows (i.e. OpenWatcom is hopeless and VC6 probably too) but this
shouldn't worry you, as a user, as you can choose your compiler. It does
worry us, the developers, however. And this is why I think reimplementing
some of libsigc features could be more practical and mroe useful for us.

Regards,
VZ
Stefan Csomor
21 years ago
Permalink
Hi

Yes, right now XTI is exposing events using the Connect mechanism, we might
propagate these event connection points to C++. The question on which
compilers we should support this remains valid of course

Best,

Stefan
...
k. holwerda
21 years ago
Permalink
I have used signal and slots primarily to connect my GUI widgets to
non gui storage classes ( such as an elements of a CAD model,
preferences, etc. )
Hi Max,

In the library wxArt2D, we use a mechanism of registrating event
handler to a central event distributer.
Any part of code can sent an event to the distributer, and it will be
distributed to all registrated
objects. The object(s) receiving the event, can now decide if it wants
to do something or not.
The event can of course be received by all wxEvtHandler derived classes.
Actually we have a small seperate wxCanvasObjectEvtHandler, to have
canvas object receive such events.
All in all it is used to communicate changes in the state of certain
thing to all classes interested, but
the sender of the event does not have to know the receivers.
Simular mechanism might also by setup to do this signal slot thing.
Althoughi never understood what is really
the problem here. In any case you can call processevent an event
handling object from somewhere else.
So what is this signal slot offereing more?

Regards,

Klaas
--
Unclassified
Max
21 years ago
Permalink
...
AFAIK, you are mentioning events in the sense that there are passing
thru the regular GUI event loop.

Signal-Slot mechanism is synchronous, that is the the slots methods will
be called immediately after the signal is emitted. In certain cases,
async events are troublesome.

Another advantage is references can be passed from signals to slots so
there is no memory overhead. If event objects were used, the events
would take space in the memory.

Additionaly slots are methods, therefore a signal is connected to a
slot. Therefore there is no need to write a custom event handler method
and have a switch-case with memory casts or dynamics casts in it. IMHO
the code is therefore simplified.

From the Qt help :

When a signal is emitted, the slots connected to it are executed
immediately, just like a normal function call. The signal/slot mechanism
is totally independent of any GUI event loop. The emit will return when
all slots have returned.
If several slots are connected to one signal, the slots will be executed
one after the other, in an arbitrary order, when the signal is emitted.

Hope it adds some more clarity to discussion.

Max.
Post by k. holwerda
Regards,
Klaas
Vadim Zeitlin
21 years ago
Permalink
On Wed, 05 May 2004 15:49:33 +0200 Max <***@machsim.com> wrote:

M> AFAIK, you are mentioning events in the sense that there are passing
M> thru the regular GUI event loop.

Just for the record, normal events in wxWindows *are* synchronous.

Regards,
VZ
Lothar Behrens
21 years ago
Permalink
M> AFAIK, you are mentioning events in the sense that there are passing =
M>
thru the regular GUI event loop.
Just for the record, normal events in wxWindows *are* synchronous.
Hi,

apart from the whole discussion yet, I have written a general
wxWidgets application that uses my system for managing or
connecting events to handlers.

In the wxWidgets app I have one hardcoded eventhandler (macros),
that can handle exit, about and similar standard events.

Is the event ID not in that #defined EV_ID_XX1... it calls an
event dispatcher, wich knows about other ID's - that in my way
are ID's > 5000.

The dispatcher then looks up the matching event handler for that
ID by using a skiplist and forwards the event to the registered event
handler. This then handles it and returns.

The registration of a new handler is done by calling a function from
my event manager. This class registers a symbolic event name and
returns an increased event ID.

If these ID's are registered, I can register it's handlers. Either by
using again the symbolic event names or by prior retrieved and stored
ID's.

These event handlers may or may not located in a wxWidget based
application module.

To issue an event I need to add a menu entry on the wx side.
I use my registered event handler (in the wx GUI - since I need
access to wx functionality) to build up a menu entry from non wx
modules.

Now the wx GUI user can issue a dynamically registered event from the
GUI that goes to a module unknown by the wx application.



I hope this will give another ideas for managing signals and slots.
This currently works with wxWigrets, but may also interconnect to
the signals and slot approach.



-- non wx
|
wx -| my approach (like COM with interfaces) -- signals and slot
|
-- other


Regards,

Lothar

Here is the sample code, I have extracted from my project:
(I need to think about more macros to simplify the code :-)


wx loads a module 'metaapplication' and initializes it:
(Calling this member)

lbErrCodes LB_STDCALL lb_MetaApplication::Initialize() {

// Variables that should be defined in the class decls.

int getBasicApplicationInfo;
int getMainModuleInfo;
int testPressed;

// I get my event manager by the interface name

lb_I_Module* m =3D *&manager;
REQUEST(m, lb_I_EventManager, eman)

// I register my event names and get the ID's

eman->registerEvent("getBasicApplicationInfo",
getBasicApplicationInfo);
eman->registerEvent("getMainModuleInfo", getMainModuleInfo);
eman->registerEvent("Button Test pressed", testPressed);

// I get my dispatcher

REQUEST(m, lb_I_Dispatcher, disp)
dis->setEventManager(eman.getPtr());

// I register my handlers to the given dispatcher
lbErrCodes LB_STDCALL
lb_MetaApplication::registerEventHandler(lb_I_Dispatcher* disp) {
disp->addEventHandlerFn(this, (lbEvHandler)
&lb_MetaApplication::lbEvHandler1, "getBasicApplicationInfo");
disp->addEventHandlerFn(this, (lbEvHandler)
&lb_MetaApplication::lbEvHandler2, "getMainModuleInfo");
disp->addEventHandlerFn(this, (lbEvHandler)
&lb_MetaApplication::lbButtonTestHandler, "Button Test pressed");
}

/* These has interconnected the event handler - now the menu */

addMenuBar("Edit");

loadApplication(); // let subsequent modules initialize their menu

addMenuBar("Help");

// Add some menu entries and buttons that do something

addMenuEntry("Help", "MainModuleInfo", "getMainModuleInfo", "");

addButton("Press me for test", "Button Test pressed", 10, 30, 100,
20);

int hight =3D 60;
int n =3D 1;

addLabel("Label", 115, 30, 100, 20);
addTextField("TextField", 220, 30, 100, 20);


addButton("|<", "Button Test pressed", 10, hight+n*20+n*5, 100, 20);
addButton("<<", "Button Test pressed", 115, hight+n*20+n*5, 100, 20);
addButton(">>", "Button Test pressed", 220, hight+n*20+n*5, 100, 20);
addButton(">|", "Button Test pressed", 325, hight+n*20+n*5, 100, 20);
n++;
addButton("|<", "Button Test pressed", 10, hight+n*20+n*5, 100, 20);
addButton("<<", "Button Test pressed", 115, hight+n*20+n*5, 100, 20);
addButton(">>", "Button Test pressed", 220, hight+n*20+n*5, 100, 20);
addButton(">|", "Button Test pressed", 325, hight+n*20+n*5, 100, 20);
---- My home: www.lollisoft.de -----------------------------
Lothar Behrens | Independent: ***@gmx.de
Rosmarinstr 3 | My public project:
40235 D=FCsseldorf | http://sourceforge.net/projects/lbdmf
| -> Need comments, please visit :-)
klaas.holwerda
21 years ago
Permalink
Just for my understanding, Max,
Post by Max
AFAIK, you are mentioning events in the sense that there are passing
thru the regular GUI event loop.
Signal-Slot mechanism is synchronous, that is the the slots methods
will be called immediately after the signal is emitted. In certain
cases, async events are troublesome.
As Vadim says, processevent does it directly, with some extra
flexibility that an event table acts like a virtual function more or less.
Also there is no event loop involved, ProcessEvent is directly
redirecting the event to the class, it is in fact a member function of
the base.
So one can have predifined default handlers, and users can easily
use/overrule them in a derived class.
At the same time being able to Skip the event to the base classes when
he wants.
How would that work for Signal Slot?
Post by Max
Another advantage is references can be passed from signals to slots so
there is no memory overhead. If event objects were used, the events
would take space in the memory.
We do this too. We use smart pointers, so data is flowing around as part
of the events. So no copies needed, the event just takes
an extra ownership, and releases it when done.
But as far as i know most events are references?
So i think i am missing something here?
Post by Max
Additionaly slots are methods, therefore a signal is connected to a
slot. Therefore there is no need to write a custom event handler
method and have a switch-case with memory casts or dynamics casts in
it. IMHO the code is therefore simplified.
What do you mean here, event handle tables is to me more equivalent to
the definition of a slot to signal connection.

BEGIN_EVENT_TABLE(wxCanvasStToolContr, wxCanvasToolContr)
EVTREF_CANVAS_EVENT( wxCanvasStToolContr::OnCanvasEvent )
END_EVENT_TABLE()

void wxCanvasStToolContr::OnCanvasEvent( wxCanvasEvent& event ) {....}

This here is really connecting an event to a member function.
How does this look like in Qt ?

I finaly like to understand this difference, if it is much better and
easier, i might be able to use it. libsigc++ that is ;-)
But sofar i have not seen something that is not already easy enough to
do like it is.

Signal to N slots => event sent to event distributer, all registered
class instances will get it.
Signal to 1 Slot => event sent to class using ProcessEvent and event table.

Maye a little more to do, but comes close i think?

Regards,

Klaas

Continue reading on narkive:
Loading...