Signals-slots: what am I doing wrong

I am using root 5.16 on Windows XP.

I tried to make a simple signals-slots project work with Visual Studio 8.0 but my function Worker::act() never got called. Could someone identify what I am doing wrong?

//---Worker.cpp
#include "Worker.h"
#include "TTimer.h"

#include <iostream>
#include <windows.h>

void 
Worker::act()
{
    std::cout << "QKRQ\n"; 
}

int main(int argc, char **argv)
{
    Worker *worker = new Worker();
    TTimer *timer = new TTimer(1000); 
    timer->Connect("Timeout()", "Worker", worker, "act()");

    int i = 0;
    while (i < 10)
    {
        i++;
        Sleep(1000);
    }

    return 0;
}
//---Worker.h
#ifndef SAW_WORKER
#define SAW_WORKER

class Worker
{
public:
    // Construction
    Worker() {} 
    virtual ~Worker() {}

    // Operations
    void act();
};

#endif

I do generate a dictionary via a Pre-Build Event:

rootcint -f WorkerDict.cxx -c Worker.h LinkDef.h

I assume I am doing something foolish but cant see what just now. I also attach the project to this message if that helps.

Thanks,
Sanjeev
testSlot.zip (10.7 KB)

  1. Read: root.cern.ch/phpBB2/viewtopic.php?t=5424
  2. Read: root.cern.ch/phpBB2/viewtopic.php?t=5411
  3. Rename Worker.cpp to worker.cpp
  4. Change your worker.cpp code as follows:[code]//—Worker.cpp
    #include “Worker.h”
    #include “TTimer.h”
    #include “Riostream.h”

void
Worker::act()
{
std::cout << “QKRQ\n”;
}

int worker()
{
Worker *wrk = new Worker();
TTimer *timer = new TTimer(1000);
timer->Connect(“Timeout()”, “Worker”, wrk, “act()”);
timer->Start();
return 0;
} [/code]
5. Run ROOT AClIC session as follows:

root.exe -b -l worker.cpp++Please, try that. This way you should get what you want:

[code]C:\examples>root.exe -b -l worker.cpp++

Welcome to the ROOT tutorials

root [0]
Processing worker.cpp++…
Info in TWinNTSystem::ACLiC: creating shared library C:\cygwin\home\Fine\work\ROOT\5.14\examples\worker_cpp.dll
23092187_cint.cxx
sd0k_.cxx
Creating library C:\cygwin\home\Fine\work\ROOT\5.14\examples\worker_cpp.lib and object C:\cygwin\home\Fine\work\ROOT\5.14\examples\worker_cpp.exp
(int)0
root [1] QKRQ
QKRQ
QKRQ
QKRQ
QKRQ
QKRQ
QKRQ
QKRQ

*** Break *** keyboard interrupt (0)

C:\examples>[/code]

Hi Valeri,

Thanks for the quick response. I am a bit confused. I would like to work within VS 8.0 if possible like in
root.cern.ch/phpBB2/viewtopic.ph … ht=listbox (this project runs ok for me).

  1. Do I need to rename my main function to worker? Than do I create another main which calls worker?
//---Worker.cpp
#include "Worker.h"
#include "TTimer.h"
#include "Riostream.h"

void worker();

void 
Worker::act()
{
    std::cout << "QKRQ\n"; 
}

void worker()
{
    Worker *wrk = new Worker();
    TTimer *timer = new TTimer(1000); 
    timer->Connect("Timeout()", "Worker", wrk, "act()");

    timer->Start();
}

int main(int argc, char **argv)
{
    worker();    
    return 0;
}
  1. I did rename my files to lowercase worker.h/cpp but when I run I see the same behavior (ie Worker::act() is not called).

  2. Is the issue perhaps in how I generate the dictionary? Does this now act on the function worker or the class Worker?

rootcint -f workerDict.cxx -c worker.h LinkDef.h
  1. Here is the LinkDef.h file I use
#ifdef __CINT__

#pragma link off all globals; 
#pragma link off all classes; 
#pragma link off all functions; 

#pragma link C++ class Worker; 

#endif 

Confused,
Sanjeev

p.s. I attach the sln file I am using if you try to duplicate what I am seeing.[/code]
testSlot.zip (14.1 KB)

[quote=“supandey”]Hi Valeri,

Thanks for the quick response. I am a bit confused. I would like to work within VS 8.0 if possible like in
root.cern.ch/phpBB2/viewtopic.ph … ht=listbox (this project runs ok for me).[/quote]before going further can you try what I had suggested? Does it work for you?

You do not need to create another main because I suggested you to try the simple things first. Namely, I advised to use ACLiC. I supposed it should take you about 2-3 min to try. As soon as you comfortable with that solution one may discuss how to write properly one’s own customized ROOT application. The good example of such kind of the application can be found under $ROOTSYS/test/hworld.cxx .

[quote=“supandey”]
2) I did rename my files to lowercase worker.h/cpp but when I run I see the same behavior (ie Worker::act() is not called). [/quote]Did you mean you had being following my 5 points “plan” step-by-step and did not get any printout from “act()” method?[quote=“supandey”]
3) Is the issue perhaps in how I generate the dictionary? Does this now act on the function worker or the class Worker?

rootcint -f workerDict.cxx -c worker.h LinkDef.h
  1. Here is the LinkDef.h file I use
#ifdef __CINT__

#pragma link off all globals; 
#pragma link off all classes; 
#pragma link off all functions; 

#pragma link C++ class Worker; 

#endif 

Confused,
Sanjeev
p.s. I attach the sln file I am using if you try to duplicate what I am seeing.[/code][/quote]From the first glance your code lacks of the “event loop” (check again $ROOTSYS/test/hworld.cxx, look up for " theApp.Run();" there). However, I have no time to evaluate this approach further. I did not use it myself. I did tell you how I solve such sort of the problems and shared my experience. Probably, your the task can be solved differently and you should wait someone else to teach you that.
First one has to understand your real task.
Can you explain that? My guess ( I hate guess jobs though) based on your original code is that you want something like TThread rather TTimer. Did you see the difference?

Hi Valeri,

Apologies. I should have been more clear. I did follow what you suggested and its works

C:\QVCS\dev\root\testSlot>root.exe -b -l worker.cpp++
root [0]
Processing worker.cpp++...
Info in <TWinNTSystem::ACLiC>: creating shared library C:\QVCS\dev\root\testSlot\worker_cpp.dll
2436078_cint.cxx
s7s8_.cxx
   Creating library C:\QVCS\dev\root\testSlot\worker_cpp.lib and object C:\QVCS\dev\root\testSlot\worker_cpp.exp

(int)0
root [1] QKRQ
QKRQ
QKRQ
QKRQ
QKRQ
.         q

C:\QVCS\dev\root\testSlot>
  1. My aim was to create a minimal application showing signal-slots working within a console VS 8.0 application. I have been using test/hworld.cxx as my template for developing. That works fine. However, when I tried adding signal-slots to it I could not get them to work hence I created the minimal project above to try to isolate what I was doing wrong. I assumed I did not need TApplication/event-loop to get signal-slots to work. Is this false?

  2. My aim is to follow the suggestion in
    root.cern.ch/phpBB2/viewtopic.ph … pplication
    ie I want to update some TH2D’s after theApp.Run() has been called.

  3. Poking around some more it appears I am missing the RQ_OBJECT macro and the ClassDef declaration. I added them but still have no luck getting things to work.

//---Worker.h
#ifndef SAW_WORKER
#define SAW_WORKER

#include "RQ_Object.h"

class Worker
{
    RQ_OBJECT("Worker")
public:
    // Construction
    Worker() {} 
    virtual ~Worker() {}

    // Operations
    void act();

    ClassDef(Worker, 0)
};

#endif

If you have any other ideas I would appreciate them.

Regards,
Sanjeev

It looks like I did indeed need the eventloop. The following works

//---Worker.cpp
#include "Worker.h"
#include "TApplication.h"
#include "TTimer.h"
#include "Riostream.h"

ClassImp(Worker)

void 
Worker::act()
{
    std::cout << "QKRQ\n"; 
}

int main(int argc, char **argv)
{
    TApplication theApp("App", &argc, argv);
    
    Worker *wrk = new Worker();
    TTimer *timer = new TTimer(1000); 
    timer->Connect("Timeout()", "Worker", wrk, "act()");

    timer->Start();

    theApp.Run();

    return 0;
}

Thanks for your help Valeri.

Sanjeev
testSlot.zip (44.1 KB)

[quote=“supandey”]
1). . . .I assumed I did not need TApplication/event-loop to get signal-slots to work. Is this false?
[/quote] It is TRUE.

[quote=“supandey”] …
If you have any other ideas I would appreciate them.
[/quote] … However you do need the event loop to make TTimer work !!!