How to Embed a TCanvas in External Applications?

Here is a short HOWTO showing the few steps required to embed a TCanvas in an application created with toolkits as QT, FOX, MFC, and probably many more.

IMPORTANT: Do not call TApplication::Run()

  • In the application constructor or in main(), create a TApplication
   // create an instance of TApplication
   gMyRootApp = new TApplication("My ROOT Application", &argc, argv);

   // tell application to return from run
   gMyRootApp->SetReturnFromRun(true);
  • Create a timer to process Root events, e.g.:
   void MyWindow::OnRefreshTimer() {
      // Process Root events when a timer message is received
      gApplication->StartIdleing();
      gSystem->InnerLoop();
      gApplication->StopIdleing();
   }
  • Get the id of the window where you want to embed the TCanvas :
   void MyWindow::Create() {
      // Add this window to TVirtualX list of windows
      // in return get its TVirtualX identifier
      int wid = gVirtualX->AddWindow((ULong_t)getid(), getWidth(), getHeight());

      // Create a new TCanvas, specifying this windows id as parent
      fCanvas = new TCanvas("fCanvas", getWidth(), getHeight(), wid);
   }
  • Forward messages to the Canvas, e.g.:
   void MyWindow::OnPaint() {
      // Handle Paint events
      if (fCanvas) fCanvas->Update();
   }

   void MyWindow::OnSize() {
      // Handle Resize events
      if (fCanvas) fCanvas->Resize();
   }

   void MyWindow::OnMouseMove() {
      // Handle Mouse move events
      if (!fCanvas) return;
      if (ev->state & LEFTBUTTONMASK)
         fCanvas->HandleInput(kButton1Motion, ev->win_x, ev->win_y);
      else 
         fCanvas->HandleInput(kMouseMotion, ev->win_x, ev->win_y);
   }

   void MyWindow::OnLMouseDown() {
      // Handle Mouse Left button down event
      if (fCanvas) fCanvas->HandleInput(kButton1Down, ev->x, ev->y);
   }

Here is a screenshot of a TCanvas embedded in a simple (minimal) Qt application:
image