Error: slot DoDraw() does not exist

Hi everyone,

Im having problems with linking the dictionary under MSVC++ 8.0 express edition with windows XP.
I am trying to run the simple program listed on page 371 of the manual.
The code builds fine but when i execute it, i get “Error in : slot DoDraw() does not exit” in the console and the canvas pops up with the appropriate buttons but the Draw button does not work.
I know that such error messages occur when the dictionary is not properly linked. I am not certain how this is done in MSVC++ other than to include the ex2aLinkDef.h file.
The code is below so take a look.
and help would be appriciated.

Thanks!
John.

ex2aLinkDef.h:

#pragma link C++ class MyMainFrame;

example.h:

#include
#include <RQ_OBJECT>
#include "ex2aLinkDef.h"
class TGWindow;
class TGMainFrame;
class TRootEmbeddedCanvas;

class MyMainFrame
{
RQ_OBJECT(“MyMainFrame”)

private:
TGMainFrame *fMain;
TRootEmbeddedCanvas *fEcanvas;
public:
MyMainFrame(const TGWindow *p,UInt_t w,UInt_t h);
virtual ~MyMainFrame();
void DoDraw();

};

example.cxx:

#include
#include
#include
#include
#include
#include
#include
#include “example.h”
#include “ex2aLinkDef.h”

MyMainFrame::MyMainFrame(const TGWindow *p,UInt_t w,UInt_t h)
{
// Create a main frame
fMain = new TGMainFrame(p,w,h);
// Create canvas widget
fEcanvas = new TRootEmbeddedCanvas(“Ecanvas”,fMain,200,200);
fMain->AddFrame(fEcanvas, new TGLayoutHints(kLHintsExpandX| kLHintsExpandY,10,10,10,1));
// Create a horizontal frame widget with buttons
TGHorizontalFrame *hframe = new TGHorizontalFrame(fMain,200,40);
TGTextButton *draw = new TGTextButton(hframe,"&Draw");
draw->Connect(“Clicked()”,“MyMainFrame”,this,“DoDraw()”);
hframe->AddFrame(draw, new TGLayoutHints(kLHintsCenterX,5,5,3,4));
TGTextButton *exit = new TGTextButton(hframe,"&Exit", “gApplication->Terminate(0)”);
hframe->AddFrame(exit, new TGLayoutHints(kLHintsCenterX,5,5,3,4));
fMain->AddFrame(hframe, new TGLayoutHints(kLHintsCenterX,2,2,2,2));
// Set a name to the main frame
fMain->SetWindowName(“Simple Example”);
// Map all subwindows of main frame
fMain->MapSubwindows();
// Initialize the layout algorithm
fMain->Resize(fMain->GetDefaultSize());
// Map main frame
fMain->MapWindow();
}

MyMainFrame::~MyMainFrame()
{ //Clean up used widgets: frames, buttons, layouthints
fMain->Cleanup();
delete fMain;

}

void MyMainFrame::DoDraw()
{ // Draws function graphics in randomly choosen interval
TF1 *f1 = new TF1(“f1”,“sin(x)/x”,0,gRandom->Rndm()*10);
f1->SetFillColor(19);
f1->SetFillStyle(1);
f1->SetLineWidth(3);
f1->Draw();
TCanvas *fCanvas = fEcanvas->GetCanvas();
fCanvas->cd();
fCanvas->Update();
}

void example()
{ // Popup the GUI…
new MyMainFrame(gClient->GetRoot(),200,200);
}

int main(int argc, char **argv)
{
TApplication theApp(“App”,&argc,argv);
example();
theApp.Run();
return 0;
}

I can run your example after some trivial changes (see below)
In interactive ROOt, do

root > .L example.C root > example()

//file example.h

[code]#include
#include <RQ_OBJECT>
//#include "ex2aLinkDef.h"
class TGWindow;
class TGMainFrame;
class TRootEmbeddedCanvas;

class MyMainFrame
{
RQ_OBJECT(“MyMainFrame”)

private:
TGMainFrame *fMain;
TRootEmbeddedCanvas *fEcanvas;
public:
MyMainFrame(const TGWindow *p,UInt_t w,UInt_t h);
virtual ~MyMainFrame();
void DoDraw();

};
[/code]

//file example.C

[code]#include
#include
#include
#include
#include
#include
#include
#include “example.h”
//#include “ex2aLinkDef.h”

MyMainFrame::MyMainFrame(const TGWindow *p,UInt_t w,UInt_t h)
{
// Create a main frame
fMain = new TGMainFrame(p,w,h);
// Create canvas widget
fEcanvas = new TRootEmbeddedCanvas(“Ecanvas”,fMain,200,200);
fMain->AddFrame(fEcanvas, new TGLayoutHints(kLHintsExpandX| kLHintsExpandY,10,10,10,1));
// Create a horizontal frame widget with buttons
TGHorizontalFrame *hframe = new TGHorizontalFrame(fMain,200,40);
TGTextButton *draw = new TGTextButton(hframe,"&Draw");
draw->Connect(“Clicked()”,“MyMainFrame”,this,“DoDraw()”);
hframe->AddFrame(draw, new TGLayoutHints(kLHintsCenterX,5,5,3,4));
TGTextButton *exit = new TGTextButton(hframe,"&Exit", “gApplication->Terminate(0)”);
hframe->AddFrame(exit, new TGLayoutHints(kLHintsCenterX,5,5,3,4));
fMain->AddFrame(hframe, new TGLayoutHints(kLHintsCenterX,2,2,2,2));
// Set a name to the main frame
fMain->SetWindowName(“Simple Example”);
// Map all subwindows of main frame
fMain->MapSubwindows();
// Initialize the layout algorithm
fMain->Resize(fMain->GetDefaultSize());
// Map main frame
fMain->MapWindow();
}

MyMainFrame::~MyMainFrame()
{ //Clean up used widgets: frames, buttons, layouthints
fMain->Cleanup();
delete fMain;

}

void MyMainFrame::DoDraw()
{ // Draws function graphics in randomly choosen interval
TF1 *f1 = new TF1(“f1”,“sin(x)/x”,0,gRandom->Rndm()*10);
f1->SetFillColor(19);
f1->SetFillStyle(1);
f1->SetLineWidth(3);
f1->Draw();
TCanvas *fCanvas = fEcanvas->GetCanvas();
fCanvas->cd();
fCanvas->Update();
}

void example()
{ // Popup the GUI…
new MyMainFrame(gClient->GetRoot(),200,200);
}
[/code]

Rene

Hi,

yeah it does work under interactive root. What i was trying to do was build an .exe file under windows VC++. The canvas seems to work but not the draw buttons.
Any idea how to properly link the dictionary under windows?

John

Hi,

you should just run “.x example.C+” - which compiles your script, builds a library, loads it, and runs example(). This is far easier than setting up a Makefile, esp. with MSVC8’s manifest torture… If this is absolutely not an option, you can e.g. set “gDebug=7” before executing “.x example.C+” to see which commands are executed to build the library. Converting these commands to generate a .exe is pretty straight forward.

I’d recommend the platform independent, easy to use “.x example.C+”.

Axel.

Axel,

Note that in this particular case
.x example.C
or
.x example.C+
work correctly. I have no problems on linux, windows and Mac with this simple example.

Rene

Alright if you had problems like me with VC++8.0, trying to do things outside interactive root, heres how to do it.

if you get a slot not found problem you have to build a dictionary. To do this in VC++8.0, outside the root session, i have to go to Project->Property-> and select the Build Events catagory.
Under Pre-build Events, I am able to enter commands at the command line. This is where I entered: “rootcint -f progNameDict.cxx -c progName.h progNameLinkDef.h” . I then have to make the empty source file progNameDict.cxx. then you build and compile like normal and the exe is supposed to work.
*Note that the string LinkDef has to in the Def file. if you named the file progNameDef.h it will not work!!

also dont forget to include libCint.lib.

Thanks to anyone that offered any help.

John