ROOT Version: 6.18/04
Platform: Ubuntu 18.04
Compiler: gcc 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04)
Dear co-rooters,
I’m building a GUI that will unpack some signals and then draw them. What I would like to do is connect a widget (i.e. a button) with external functions.
I have divided my code to practically 3 parts: gui (.cxx, .h) in which a class MainFrame
is defined, unpacker (.cxx, .h) which will unpack the signals and main (.cxx, .h) which will execute any functions.
I compiled everything and I haven’t encountered any issue either in the generation of the dictionary
rootcling -f exDict.cxx -c -p main.h gui.h unpacker.h exLinkDef.h
or in the compilation using
g++ -o SignalViewer main.cxx gui.cxx unpacker.cxx exDict.cxx `root-config --cflags --glibs`
However when I run the executable I get the following error
Error in TQObject::CheckConnectArgs: slot MainFrame::test_unpack() does not exist
This is because the gui cannot see any external function, but I’m not sure how to solve it. Any ideas would be more than welcome!
Thanks in advance.
I uploaded a .zip
file with the code but I am also pasting it here.
My code is (I tried to make as simple as possible)
main.cxx
//File includes
#include "main.h"
//#include "../include/gui.h"
//#include "exDict.h"
using namespace std;
int main(int argc, char *argv[]){
// Initialise
init_unpack();
TApplication theApp("App",&argc,argv);
start_gui();
theApp.Run();
return 0;
}
main.h
#ifndef MAIN_H
#define MAIN_H
#include "gui.h"
#include "unpacker.h"
#endif
unpacker.cxx
#include <iostream>
#include "unpacker.h"
using namespace std;
int init_unpack(){
cout << "***** Initialising unpacking *****" << endl;
return 0;
}
int test_unpack(){
std::cout << "***** Executing test_unpack() *****" << std::endl;
return 0;
}
unpacker.h
#ifndef UNPACKER_H
#define UNPACKER_H
using namespace std;
int init_unpack();
int test_unpack();
#endif
gui.cxx
#include "gui.h"
#include "unpacker.h"
//#include "unpacker.cxx"
MainFrame::MainFrame(const TGWindow *p, UInt_t width, UInt_t height):TGMainFrame(p, width, height, kMainFrame|kHorizontalFrame)
{
//---- Left Frame - for buttons and user values
fr_left = new TGVerticalFrame(this, 0.3*width, height, kChildFrame|kFixedSize);
// The 1st grouped frame - runs
fr_runs = new TGGroupFrame(fr_left, "Run", kChildFrame | kVerticalFrame|kFixedSize);
box_run = new TGNumberEntry(fr_runs, (Double_t) 0, 10, -1, (TGNumberFormat::EStyle) 5);
fr_runs->AddFrame(box_run, new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 2, 2, 2, 2) );
fr_left->AddFrame(fr_runs, new TGLayoutHints(kLHintsExpandX, 2, 2, 2, 2));
// The 2nd grouped frame - Drawing the signal
fr_draw = new TGGroupFrame(fr_left, "Draw", kChildFrame | kHorizontalFrame|kFixedSize);
TGTextButton *but_draw_histo = new TGTextButton(fr_draw, "&Draw");
but_draw_histo->Connect("Clicked()", "MainFrame", this, "test_unpack()");
fr_draw->AddFrame(but_draw_histo, new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 2, 2, 2, 2) );
fr_left->AddFrame(fr_draw, new TGLayoutHints(kLHintsExpandX, 2, 2, 2, 2));
// Test button to see the structure
TGTextButton *test = new TGTextButton(fr_left,"&Test");
test->Connect("Clicked()", "MainFrame", this, "draw_test()");
fr_left->AddFrame(test, new TGLayoutHints(kLHintsCenterX | kLHintsCenterY, 10, 10, 10, 10) );
// Exit button to exit the application
TGTextButton *exit = new TGTextButton(fr_left, "&Exit", "gApplication->Terminate(0)");
fr_left->AddFrame(exit, new TGLayoutHints(kLHintsCenterX, 5, 5, 3, 4) );
AddFrame(fr_left , new TGLayoutHints(kLHintsLeft | kLHintsTop, 10,10,10,10));
//---- Right frame - for the canvas
TGVerticalFrame *fr_right = new TGVerticalFrame(this, 0.7*width, height, kChildFrame);
emb_canvas = new TRootEmbeddedCanvas("canvas", fr_right, 130, 180);
fr_right->AddFrame(emb_canvas, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY, 10,10,10,10));
AddFrame(fr_right , new TGLayoutHints(kLHintsExpandX | kLHintsExpandY, 10,10,10,10));
// Set a name to the main frame
SetWindowName("Signal viewer");
// Map all subwindows of main frame
MapSubwindows();
Layout();
// Initialize the layout algorithm
Resize(GetDefaultSize());
// Map main frame
MapWindow();
}
////////////////////////////////////////////////////////////////////////////////
/// Handles resize events for the mainframe.
Bool_t MainFrame::HandleConfigureNotify(Event_t *event)
{
// set the size minus the margins set in the LayoutManager:
// AddFrame(fr_left , new TGLayoutHints(kLHintsLeft | kLHintsTop, 10,10,10,10));
UInt_t w = event->fWidth-20;
UInt_t h = event->fHeight-20;
fr_runs->Resize(0.25*w, 0.15*h);
fr_runs->Layout();
fr_draw->Resize(0.25*w, 0.15*h);
fr_draw->Layout();
fr_left->Resize(0.25*w, h);
fr_left->Layout();
return TGMainFrame::HandleConfigureNotify(event);
}
void MainFrame::draw_test() {
// Draws function graphics in randomly chosen interval
TF1 *f1 = new TF1("f1","sin(x)/x",0,gRandom->Rndm()*10);
f1->SetLineWidth(3);
f1->Draw();
TCanvas *fCanvas = emb_canvas->GetCanvas();
fCanvas->cd();
fCanvas->Update();
}
MainFrame::~MainFrame() {
// Clean up used widgets: frames, buttons, layout hints
Cleanup();
}
void start_gui(){
// Popup the gui
std::cout << "Starting the gui" << std::endl;
new MainFrame(gClient->GetRoot(), 800, 500);
}
//int test_unpack();
gui.h
#ifndef ___GUI_H
#define ___GUI_H
//ROOT Includes
#include "TFile.h"
#include <TGClient.h>
#include <TCanvas.h>
#include <TF1.h>
#include "TH1F.h"
#include "TPaveText.h"
#include <TRandom.h>
#include <TGButton.h>
#include <TGFrame.h>
#include <TGNumberEntry.h>
#include <TRootEmbeddedCanvas.h>
#include <TApplication.h>
#include <TGClient.h>
#include <RQ_OBJECT.h>
#include "unpacker.h"
//#include "exLinkDef.h"
using namespace std;
class MainFrame : public TGMainFrame {
private:
TRootEmbeddedCanvas *emb_canvas;
TGVerticalFrame *fr_left;
TGGroupFrame *fr_runs, *fr_draw;
TGNumberEntry *box_run;
public:
MainFrame(const TGWindow *p, UInt_t width, UInt_t height);
Bool_t HandleConfigureNotify(Event_t *);
virtual ~MainFrame();
void draw_test();
ClassDef (MainFrame,0);// Remove for ROOT6 and rootcling
};
void start_gui();
//int test_unpack();
#endif
signal_viewer_forum.zip (4.8 KB)