Dear professionals,
please help me with this problem.
I write GUI for online monitor.
I want to have two threads: one is responsible for GUI and another for data acquisition.
I have analogous program in Qt and it works perfectly, but my new program should be in root cern and I have some difficulties.
It is my simple compiled example which reproduce the problem:
main.cpp
#include <TApplication.h>
#include <TGClient.h>
#include <TCanvas.h>
#include <TF1.h>
#include <TRandom.h>
#include <TGButton.h>
#include <TRootEmbeddedCanvas.h>
//my
#include "mymainframe.h"
int main(int argc, char **argv)
{
printf("You are in master Thread \n");
TApplication theApp("App",&argc,argv);
Worker *worker = new Worker();
MyMainFrame *my_mframe = new MyMainFrame();
worker->Connect("SendValue(Long_t)","MyMainFrame",my_mframe,"Draw_Graphs(Long_t)");
theApp.Run();
return 0;
}
mymainframe.h
#ifndef MYMAINFRAME_H
#define MYMAINFRAME_H
#include "worker.h"
class MyMainFrame
{
RQ_OBJECT("MyMainFrame")
public:
MyMainFrame();
void Draw_Graphs(Long_t cnt);
private:
Long_t counter;
};
#endif // MYMAINFRAME_H
worker.h
#ifndef WORKER_H
#define WORKER_H
#include "TThread.h"
#include <Riostream.h>
//root cern GUI
#include <TGClient.h>
#include <TGButton.h>
#include <TRootEmbeddedCanvas.h>
#include "TGFrame.h"
#include "TGTab.h"
#include <TQObject.h>
#include <RQ_OBJECT.h>
class Worker
{
RQ_OBJECT("Worker")
private:
static std::vector<Int_t> fValue_vec;
static Long_t counter;
static TThread *h1;
public:
Worker();
void SendValue(Long_t); // *SIGNAL*
static void *handle(void *ptr);
};
#endif // WORKER_H
linkdef.h
#pragma link C++ class Worker;
#pragma link C++ class MyMainFrame;
mymainframe.cpp
#include "mymainframe.h"
MyMainFrame::MyMainFrame()
{
}
void MyMainFrame::Draw_Graphs(Long_t cnt)
{
//dummy
printf("You are in master Thread: event %d: %d, %d, %d \n", cnt);
//printf("You are in master Thread: at event %d values are is: %d, %d, %d \n", counter, vec[0], vec[1], vec[2]);
}
worker.cpp
#include "worker.h"
std::vector<Int_t> Worker::fValue_vec(0);
Long_t Worker::counter = 0;
TThread *Worker::h1 = new TThread("h1", Worker::handle);
Worker::Worker()
{
h1->Run();
}
void Worker::SendValue(Long_t cnt)
{
Emit("SendValue(Long_t)",cnt);
}
void *Worker::handle(void *ptr)
{
vector<Int_t> vec(3);
//Long_t counter = 0;
while(1)
{
//some work to get data (read board or file)
gSystem->Sleep(1000);//dummy
vec[0] = counter + 10;
vec[1] = counter + 20;
vec[2] = counter + 30;
//I want to send new data to master thread.
//How?
//
SendValue(counter);// see the next error:
//worker.cpp: In static member function ‘static void* Worker::handle(void*)’:
//worker.cpp:34:24: error: cannot call member function ‘void Worker::SendValue(Long_t)’ without object SendValue(counter);
//this code does not help too
//Emit("SendValue(Long_t)",counter);
printf("You are in slave Thread: at event %d values are is: %d, %d, %d \n", counter, vec[0], vec[1], vec[2]);
counter++;
}
return 0;
}
To launch:
rootcint -f mainDic.cpp -c mymainframe.h worker.h linkdef.h;
g++ -o main mymainframe.cpp worker.cpp main.cpp mainDic.cpp `root-config --cflags --glibs`;
./main
So, my problem how to send data from slave thread to master thread(GUI).
As I know I can get some values when thread will be finished, but in my case, I think, it will waste too many resources to open/close threads.
In Qt I just send signal from one thread to another without any problems, because signals and slots are thread-safe.
I think, should be simple solution.
Thank you in advance.