#if defined(__CINT__) && !defined(__MAKECINT__) { Info("gui_thread2.C", "Has to be run in compiled mode ... doing this for you."); gSystem->CompileMacro("gui_thread2.C"); gui_thread2(); } #else #include "TApplication.h" #include "TGClient.h" #include "TCanvas.h" #include "TF1.h" #include "TRandom.h" #include "TGButton.h" #include "TRootEmbeddedCanvas.h" #include "TH1F.h" #include "TFormula.h" #include "TTimer.h" #include "TGFrame.h" #include "TThread.h" class MyMainFrame : public TGMainFrame { private: TRootEmbeddedCanvas *fEcanvas; TGTextButton *fStartStop; TH1F *fH1f; TThread *fThread; // canvas used by the static thread method TCanvas *fC1; public: MyMainFrame(const TGWindow *p, UInt_t w, UInt_t h); virtual ~MyMainFrame() { } void CloseWindow(); void StartStop(); TThread *GetThread() const { return fThread; } TCanvas *GetCanvas() const { return fC1; } TH1F *GetHisto() const { return fH1f; } // thread method static void *ThreadFunc(void *ptr = 0); ClassDef(MyMainFrame, 0) }; const char *thread_state[] = { "Invalid", "Created", "Running", "Terminated", "Finished", "Canceling", "Canceled", "Deleting" }; //______________________________________________________________________ MyMainFrame::MyMainFrame(const TGWindow *p,UInt_t w,UInt_t h) : TGMainFrame(p,w,h), fH1f(0), fThread(0), fC1(0) { // Creates widgets of the example SetCleanup(kDeepCleanup); fEcanvas = new TRootEmbeddedCanvas ("Ecanvas",this,600,400); AddFrame(fEcanvas, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY, 10,10,10,1)); fC1 = fEcanvas->GetCanvas(); TGHorizontalFrame *hframe=new TGHorizontalFrame(this, 200,40); fStartStop = new TGTextButton(hframe,"&Start Thread"); fStartStop->Connect("Clicked()","MyMainFrame",this,"StartStop()"); hframe->AddFrame(fStartStop, new TGLayoutHints(kLHintsExpandX,5,5,3,4)); TGTextButton *exit = new TGTextButton(hframe,"&Exit ", "gApplication->Terminate()"); hframe->AddFrame(exit, new TGLayoutHints(kLHintsExpandX,5,5,3,4)); AddFrame(hframe,new TGLayoutHints(kLHintsExpandX,2,2,2,2)); if (!fH1f) { TFormula *form1 = new TFormula("form1","abs(sin(x)/x)"); form1->Update(); TF1 *sqroot = new TF1("sqroot","x*gaus(0) + [3]*form1",0,10); sqroot->SetParameters(10,4,1,20); fH1f = new TH1F("h1f","Test random numbers",100,0,10); fH1f->SetFillColor(45); fH1f->FillRandom("sqroot",10000); fC1->cd(); } // Sets window name and shows the main frame SetWindowName("Simple Example of GUI Thread"); MapSubwindows(); Resize(GetDefaultSize()); MapWindow(); // set up the thread fThread = new TThread("MyThread", ThreadFunc, (void*)this); } //______________________________________________________________________ void MyMainFrame::StartStop() { // Starts the thread if (fThread->GetState() == TThread::kRunningState) { fThread->Kill(); fStartStop->SetText("&Start Thread"); } else { fThread->Run(this); fThread->SetCancelAsynchronous(); fStartStop->SetText("&Stop Thread"); } gClient->NeedRedraw(fStartStop); } //______________________________________________________________________________ void MyMainFrame::CloseWindow() { // terminate and delete the thread, then quit the application if (fThread->GetState() == TThread::kRunningState) { fThread->Kill(); fStartStop->SetText("&Start Thread"); gClient->NeedRedraw(fStartStop); } TGMainFrame::CloseWindow(); //gApplication->Terminate(); } //______________________________________________________________________________ void *MyMainFrame::ThreadFunc(void *ptr) { // this method is called by the thread MyMainFrame *main = (MyMainFrame *)ptr; if (!main) return 0; TThread *th = main->GetThread(); TCanvas *c1 = main->GetCanvas(); TH1F *h1f = main->GetHisto(); if (!th || !c1 || !h1f) return 0; c1->cd(); h1f->Draw(); // infinite loop updating the histogram while (true) { if (th && th->GetState() != TThread::kRunningState) break; if (h1f) { // locking avoids data loss TThread::Lock(); h1f->Reset(); h1f->FillRandom("sqroot",10000); TThread::UnLock(); } c1->Modified(); c1->Update(); // sleep for 100 ms gSystem->Sleep(100); } return ptr; } //______________________________________________________________________________ void gui_thread2() { new MyMainFrame(gClient->GetRoot(), 800, 600); } #endif