Slot DoDraw() does not exist compiled guide

I am trying to assemble a compiled version of the simple example of the ROOT manual (GUI chapter). The interactive version works OK. So after correcting a few typos I ended up with this:

#include <TGFrame.h>
#include <TApplication.h>
#include <TGClient.h>
#include <TCanvas.h>
#include <TF1.h>
#include <TRandom.h>
#include <TGButton.h>
#include <TRootEmbeddedCanvas.h>

class MyMainFrame : public TGMainFrame
{
private:
  TGMainFrame *fMain;
  TRootEmbeddedCanvas *fEcanvas;
public:
  MyMainFrame(const TGWindow *p,UInt_t w,UInt_t h);
  virtual ~MyMainFrame()
  {
    fMain->Cleanup();
    delete fMain;
  }
  void DoDraw()
  {
    TF1 *f1 = new TF1("f1","sin(x)/x",0,gRandom->Rndm()*10); f1->SetLineWidth(3);
    f1->Draw();
    TCanvas *fCanvas = fEcanvas->GetCanvas();
    fCanvas->cd();
    fCanvas->Update();
  }
  //ClassDef(MyMainFrame,0)
};

MyMainFrame::MyMainFrame(const TGWindow *p,UInt_t w,UInt_t h)
: TGMainFrame(p,w,h)
{
  // Creates widgets of the example
  fEcanvas = new TRootEmbeddedCanvas ("Ecanvas",this,200,200);
  AddFrame(fEcanvas, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY, 10,10,10,1));
  TGHorizontalFrame *hframe=new TGHorizontalFrame(this, 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()");
  hframe->AddFrame(exit, new TGLayoutHints(kLHintsCenterX,5,5,3,4));
  AddFrame(hframe,new TGLayoutHints(kLHintsCenterX,2,2,2,2));                                                                                                 SetWindowName("Simple Example");
  MapSubwindows();
  Resize(GetDefaultSize());
  MapWindow();
}

void example()
{
  new MyMainFrame(gClient->GetRoot(),200,200);
}

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

It compiles and runs but then the Draw button doesn’t work:

Error in TQObject::CheckConnectArgs: slot DoDraw() does not exist


Please read tips for efficient and successful posting and posting code

_ROOT Version: 6.22.06
_Platform: MacOSX 10.14.6
_Compiler: LLVM 10.0.0 (clang-1000.11.45.2)


A ROOT program that utilizes Graphical User Interface (GUI) takes advantage of a Signal and Slot technology. In order for this technology to work in a stand-alone program it is not enough to simply compile your executable. On Linux and MacOS steps are following:

  • Create LinkDef.h file with list of classes utilizing Signals and Slots (example).
  • Use rootcling utility to generate dictionary (*.cxx and *.pcm) files from list of your headers and LinkDef.h
  • Compile shared library (.so) from your C++ source file(s) and dictionary .cxx file.
  • Compile your C++ source files into object files.
  • Link object files and shared library into executable.
  • Copy shared library *.so and dictionary *.pcm file to default system shared library search path ($DYLD_LIBRARY_PATH on macOS or $LD_LIBRARY_PATH on Linux).

Now you will be able to run the executable. Conventional way of automating the above steps is writing a Makefile. Below I attach an archive with your code and a universal GNU Makefile that will compile and install your program on MacOS or Linux.

kolev.zip (3.6 KB)

Please follow steps below to compile and run your program (on MacOS or Linux):

  • Unpack the archive, navigate inside the program folder containing Makefile.
  • In Terminal run make, followed by make install.
  • Run your program in Terminal by typing kolev

You can get familiar with the syntax of the above GNU Makefile in Chapter 6 of this manuscript.

Technically you can use Cmake to create a similar cross-platform Makefile for ROOT program that will compile and install your program on Windows computer as well. I do not have experience compiling ROOT stand-alone programs on Windows. Please refer to this post discussing options for ROOT Makefiles on Windows for more information.

1 Like

Thank you!

Hi @kolev20n, how’s it going!

In my previous post I outlined how to write a GNU Makefile for the ROOT program. It is important to understand how GNU Make works. However, alternative solution would be to use CMake project generator. Essentially CMake will create similar Makefile for you (no need to write it yourself).

CMake comes with benefits. It can generate cross-platform makefiles, detect external libraries. Most important feature I find in CMake is IDE Build tool generators. CMake can generate an project that can be opened in IDE of your choice (Eclipse, Visual Studio,…). And you can enjoy such features like code autocompletion, hilighting and debugging.

Below please find an archive with your code and universal CMakeLists.txt file that should build and install pretty much any basic ROOT-based project.

kolev-cmake.zip (5.6 KB)

Follow steps below to build and install your program (out-of-source build):

  1. Download the archive and unpack its contents to kolev folder.
  2. Create kolev-build folder in the same parent folder with kolev, navigate into kolev-build.
  3. Run following commands:
cmake ./../kolev
make -j`nproc`
sudo make install

Now you can run your program by typing kolev in the Terminal.

I tried compiling and running yor code on Linux and macOS. I’m sure Windows might require some changes to the above CMakeLists.txt. I don’t have a Windows computer to test it.

Thank you.

But, tried both with the make and make versions, and also stand-alone (I’ve done dictionaries for my own classes or STL classes and they work without a glitch), still not getting it running:

Error in TQObject::CheckConnectArgs: slot DoDraw() does not exist

Let me know.

Hi Dr. Kolev,

I apologize for the incomplete answer given above. I believed that your issue is related to the build configuration. However, there is more to it.

Now that we clarified the build steps, let us look at the code itself. According to an example in the documentation for Standalone Version, Writing a GUI we have to do the following (refer to the example2b option):

  • Uncommented ClassDef(MyMainFrame, 0) macro in definition of your MyMainFrame class.
  • Split MyMainFrame class definition and implementation into separate *.h and *.cpp files.

It turns out that both above criteria are required for the stand-alone version to work correctly. I have modified your program code to satisfy the above requirements. Please download the archive with your code below. I’m attaching the example with CMake project generator. Please note that even though the number of source and header files was changed in the project, CMakeLists.txt remains the same. It automatically builds corresponding lists of files by searching in the project folder. I favor CMake project generator option over the GNU Makefile because it comes with more possibilities.

kolev-gui.zip (3.5 KB)

Please let me know if this resolves your issue. Also please mark this post as “Solution” if everything works out well.

P.S. @kolev20n, I’ve added a minor fix to your code that correctly terminates ROOT event loop when the main GUI window is closed. Method is implemented in MyMainFrame::Exit(). You can find similar code in ROOT GUI examples.

Also it seems that correct location for the *rdict.pcm file is not in dynamic library search path, but /usr/local/bin instead. So I had to fix that in CMakeLists.txt

Works perfectly now. Thank you. Much appreciated your detailed explanations.