How to send signals to GUI

Hi, I’m using Root 3.10/02 on win XP with .net 2003

I'm building an analysis app. My data are trees in root files arranged logically in a nested directory structure. I have mirrored this structure in three classes. I have an object of Class3, with an analysis method corresponding to each root file. Objects of Class2 which contain collections of the Class3 objects, and an object of Class1 which contains a collection of the Class2 objects. 

I can call the DoAnalysis method of any Class3 object via my GUI. If I call the DoAnalysis method of a Class2 object it iterates on it's collection of Class3 objects calling the DoAnalysis method of each. Similarly calling the DoAnalysis method of the Class1 object will call the DoAnalysis method of each Class2 object (and hence each Class3 object), carrying out the analysis on all my data.

The problem I have is that I would like to update the GUI (status bar or a progress bar) with the status of the analysis.

I have a Class MyMainFrame which contains a TGMainFrame object (the GUI) with a slot to update the status bar.

I have put a signal in Class3 which is Emitted when the DoAnalysis method is called. My problem is how to connect this signal to the slot in the GUI. In the Users Guide it states…

To make a single connection from all objects of a class you should write:

TQObject::Connect(“Channel”, “AlarmOn()”, “HandlerClass”, handler, “HandleAlarm()”);

I have tried this but my slot is never called. Where should I put this call to connect the signal to the slot ? Should it be in the constructor of MyMainFrame ? (That doesn’t seem to work). Or should it be in the constructor of Class3 - If this is the case do I need to propagate a pointer to MyMainFrame down to Class3 objects ? (I’d rather not do this as at the moment they are independent of the GUI and I’d like to call those classes in batch.

Maybe my design is flawed !?

I hope this is clear enough for somebody to be able to help.

Thanks in advance

elc

OK - I have found the problem.

My Class3 is compiled but contained the RQ_OBJECT macro rather than inheriting from TQObject - I changed this and it works now (ie I can connect all objects of Class3 to my GUI with one call in the GUI class constructor).

Maybe this should be made clearer in the User Guide !?

In the online documentation

root.cern.ch/root/HowtoSignalSlot.html

it states…

The third requirement, only necessary if you want to have class signals (i.e. for all objects of a class), is that you have to replace the standard ClassImp macro by ClassImpQ.

However in TQObject.h there is the the macro is defined as…

//---- ClassImpQ macro ----------------------------------------------
//
// This macro used to correspond to the ClassImp macro and should be used
// for classes derived from TQObject instead of the ClassImp macro.
// This macro makes it possible to have a single connection from
// all objects of the same class.
// *** It is now obsolete ***

I am not using the ClassImpQ macro in my compiled Class3 but it seems to work fine (now that it inherits from TQObject). Is this macro still required for interpreted classes that want to connect all objects to a slot !?

Thanks

elc

Hi elc,

things are changing quickly … as you noticed, now

#define ClassImpQ(name) ClassImp(name)

Regards. Valeriy

Thanks for the clarification.

The online documentation

root.cern.ch/root/HowtoSignalSlot.html

states

"Signals and slots can take any number of arguments of any type. "

Is this really true ?

I was trying to get an object of MyClass to send a pointer to itself via an Emit signal

eg.

void Active(const MyClass* obj) { Emit(“Active(const MyClass*)”, obj); }; // SIGNAL

This doesn’t seem to work because TQObject::Emit() doesn’t have a signature for MyClass

This seems to restrict Signal/Slot communication to the types listed in the TQObject::Emit() methods, contradicting the statement,

"Signals and slots can take any number of arguments of any type. "

Is this the case or have I missed something ?

elc

Hi elc,

[quote=“elc”]Thanks for the clarification.

The online documentation

root.cern.ch/root/HowtoSignalSlot.html

states

"Signals and slots can take any number of arguments of any type. "

Is this really true ?

[/quote]

Da, it’s true. Here is an exampe of implemention

MyClass::MySignal(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5)
{
long val[5];

val[0] = (long)arg1;
val[1] = (long)arg2;
val[2] = (long)arg3;
val[3] = (long)arg4;
val[4] = (long)arg5;

Emit(“MySignal(type1, type2, type3, type4, type5)”, val);
}

  1. do not use “const”
  2. use as Emit(“Active(MyClass*)”, (long)obj);
  3. try to use signal arguments which are
    “as few as possible, as simple as possible”

[quote]
This doesn’t seem to work because TQObject::Emit() doesn’t have a signature for MyClass

This seems to restrict Signal/Slot communication to the types listed in the TQObject::Emit() methods, contradicting the statement,

"Signals and slots can take any number of arguments of any type. "

Is this the case or have I missed something ?

elc[/quote]

We will add correspondent comments to UserGuide.
Thanks for pointing to that.

Regards. Valeriy

Ah ok - I see now how the array of longs signature for Emit works !

(I got round it my packing my pointer into a char* but now I see how it sould be done properly (and for more than one argument).)

I take your point about signals being as simple as possible - that’s why I was sending a pointer to MyClass object - so I could call it’s Getters for feedback in the GUI, rather than sending several parameters.

Thanks very much for your help,

root rocks !

elc