Root & Qt

Ciao,
I’m doing a proof of concept application that uses QT+Root. I compiled and installed ROOT with the following options (using prebuild packages is not an option, in this case)

./configure --prefix=/sw/root --enable-table --with-dcap-libdir=/afs/cern.ch/sw/lcg/external/dcap/1.2.33/slc3_ia32_gcc323/lib --with-dcap-incdir=/afs/cern.ch/sw/lcg/external/dcap/1.2.33/slc3_ia32_gcc323/include --enable-python --enable-explicitlink --enable-qt --with-python-incdir=/afs/cern.ch/cms/external/lcg/external/Python/2.3.4/slc3_ia32_gcc323/include/python2.3 --with-python-libdir=/afs/cern.ch/cms/external/lcg/external/Python/2.3.4/slc3_ia32_gcc323/lib --with-qt-incdir=/afs/cern.ch/cms/external/lcg/external/qt/3.3.4/slc3_ia32_gcc323/include --with-qt-libdir=/afs/cern.ch/cms/external/lcg/external/qt/3.3.4/slc3_ia32_gcc323/lib --incdir=/sw/root/include --libdir=/sw/root/lib --help

and I tried something simple as follows:

#include “TGraph.h”
#include “TQtWidget.h”
#include “TCanvas.h”
#include “TGQt.h”
#include <qapplication.h>
#include <qwidget.h>

int main( int argc, char **argv )
{
QApplication *app = new QApplication (argc, argv);

TGQt tgqt;
tgqt.Init (0);
TQtWidget *MyWidget= new TQtWidget(0, "MyWidget");
 
MyWidget->show();

MyWidget->GetCanvas()->cd();
TGraph *mygraph;
float x[3] = {1,2,3};
float y[3] = {1.5, 3.0, 4.5};
mygraph  = new TGraph(3,x,y);
mygraph->SetMarkerStyle(20);
mygraph->Draw("AP");
MyWidget->GetCanvas()->Update();

app->exec ();

return 0;

}

which I compiled with

c++ -pthread -I/sw/include/root -L/sw/lib/root -lCore -lCint -lHist -lGraf -lGraf3d -lGpad -lTree -lRint -lPostscript -lMatrix -lPhysics -lGQt -pthread -lm -ldl -rdynamic -I/afs/cern.ch/cms/external/lcg/external/qt/3.3.4/slc3_ia32_gcc323/include test/test_TQtWidget.cpp

This crashes in

0x002be5c1 in TClass::New () from /sw/root/lib/libCore.so
#1 0x00b4955c in TVirtualHistPainter::HistPainter () from /sw/root/lib/libHist.so
#2 0x00add8be in TH1::GetPainter () from /sw/root/lib/libHist.so
#3 0x00ae236f in TH1::Paint () from /sw/root/lib/libHist.so
#4 0x00cd8437 in TGraph::PaintGraph () from /sw/root/lib/libGraf.so
#5 0x00cd6fe0 in TGraph::Paint () from /sw/root/lib/libGraf.so
#6 0x00f5ad67 in TPad::PaintModified () from /sw/root/lib/libGpad.so
#7 0x00f40c3d in TCanvas::Update () from /sw/root/lib/libGpad.so
#8 0x08048e67 in main ()

Further investigation suggest that the

gROOT->GetPluginManager()->FindHandler(“TVirtualHistPainter”)

returns 0 (even when issued from the root prompt).

Any idea of what I’m doing wrong? I assume I misinstalled root, but how?

Ciao,
Giulio
PS:
LD_LIBRARY_PATH=/sw/root/lib:…
PATH=/sw/root/bin:…
ROOTSYS=/sw/root

Hello
You have overcomplicated your main program.

There are TWO ways to combine ROOT and Qt packages

  1. Create Qt application
  2. Create ROOT application

For your particular case I would advice to create the ROOT application.
To do that you have to REMOVE ALL qt specific portions.
It must be “pure” ROOT one.

Like this:

#include “TApplication.h”
#include “TCanvas.h”
#include “TLine.h”
#include “TPaveLabel.h”

int main(int argc, char **argv)
{
TApplication theApp(“App”, &argc, argv);

TCanvas *c = new TCanvas(“c”, “The Hello Canvas”, 400, 400);
c->Connect(“Closed()”, “TApplication”, &theApp, “Terminate()”);

TGraph *mygraph;
float x[3] = {1,2,3};
float y[3] = {1.5, 3.0, 4.5};
mygraph  = new TGraph(3,x,y);
mygraph->SetMarkerStyle(20);
mygraph->Draw("AP");
MyWidget->GetCanvas()->Update();

 c->Update();

theApp.Run();
return 0;
}

It will become Qt-aware automatically as soon as you provide the proper “Gui.backend” parameter via “system.rootrc” or via your custom “.rootrc” ROOT resource file.
( see: root.bnl.gov/QtRoot/QtRoot.html#switch )

Please look up your $ROOTSYS/etc/system.rootrc file for the lines:

GUI specific settings.

Gui.Backend: native
Gui.Factory: native

and replace the “native” with “qt”.

GUI specific settings.

Gui.Backend: qt
Gui.Factory: qt

You can make it a little bit more flexible by using the env variable.
I.e. you can set there

GUI specific settings.

Gui.Backend: $(GUI)
Gui.Factory: $(GUI)

This allows you to switch Qt/naltive ROOT backend by setting the GUI env variable.

Let me know whether it helps.

If you want very Qt application you still have to simplify your code and you stilll have to provide the proper ROOT resource file as was pointed above. Your main code may look as follows:

include “TGraph.h”
#include “TQtWidget.h”
#include “TCanvas.h”
#include <qapplication.h>

int main( int argc, char **argv )
{
QApplication *app = new QApplication (argc, argv);

TQtWidget *MyWidget= new TQtWidget(0, “MyWidget”);

MyWidget->cd();
TGraph *mygraph;
float x[3] = {1,2,3};
float y[3] = {1.5, 3.0, 4.5};
mygraph = new TGraph(3,x,y);
mygraph->SetMarkerStyle(20);
mygraph->Draw(“AP”);
MyWidget->show();

app->exec ();

return 0;
}

Hmm :unamused: It sounds redundant for me. I’ll try to eliminate this step with next release :wink: . For the time being you have :open_mouth: to provide the proper ROOT resource file

Hello
You have overcomplicated your main program.
There are TWO ways to combine ROOT and Qt packages

  1. Create Qt application
  2. Create ROOT application

For your particular case I would advice to create the ROOT application.
To do that you have to REMOVE ALL qt specific portions.
It must be “pure” ROOT one.

Sorry, this is not an option for me. Actually the viceversa is more true. I would like to use root only as one of the possible “plotters” for my application and nothing else. For my purpose what I need is to be able to setup a TQtWidget and to be able to get a callback with the pointer to the selected object every time the selection in the TCanvas changes. Nothing more, i don’t even care about the context menu and about being able to move the objects around (and this for me is actually a requirement, not a simplification I want to make).
Anyway, I solved the first problem, which was actually an installation problem as I thought (I forgot --etcdir…). Still things don’t work. As I said the sourcecode I have is:

#include “TGraph.h”
#include “TQtWidget.h”
#include “TCanvas.h”
#include “TGQt.h”
#include <qapplication.h>
#include <qwidget.h>

int main( int argc, char **argv )
{
QApplication *app = new QApplication (argc, argv);
gVirtualX = new TGQt ();
gVirtualX->Init (0);
TQtWidget *MyWidget= new TQtWidget(0, “MyWidget”);

MyWidget->show();

MyWidget->GetCanvas()->cd();
TGraph *mygraph;
float x[3] = {1,2,3};
float y[3] = {1.5, 3.0, 4.5};
mygraph  = new TGraph(3,x,y);
mygraph->SetMarkerStyle(20);
mygraph->Draw("AP");
MyWidget->GetCanvas()->Update();

app->exec ();

return 0;

}

First of all: if I don’t add the TGQt ()->init (0) part, everything crashes because of fWidgetArray not properly initialised, is this the correct way of initialising it?
Anyway this now crashes in:

#0 0x018c7d40 in TGX11::ClearWindow () from /sw/root/lib/libGX11.so
#1 0x00f186b6 in TCanvas::Build () from /sw/root/lib/libGpad.so
#2 0x00f174fd in TCanvas::TCanvas () from /sw/root/lib/libGpad.so
#3 0x0428eee6 in TQtWidget::TQtWidget () from /sw/root/lib/libGQt.so
#4 0x08048c27 in main ()

Which seems odd to me, because I wouldn’t expect my code to use TGX11. Any idea?

Ciao,
Giulio

Ciao,
Ok, I modified the wrong resource file… :oops: Anyway, now the code you suggest crashes in

#0 0x01951cf5 in TGResourcePool::TGResourcePool () from /sw/root/lib/libGui.so
#1 0x018e418c in TGClient::TGClient () from /sw/root/lib/libGui.so
#2 0x060c7687 in TQtRootGuiFactory::CreateQClient () from /sw/root/lib/libQtRoot.so
#3 0x060c7654 in TQtRootGuiFactory::CreateApplicationImp () from /sw/root/lib/libQtRoot.so
#4 0x0074c86c in TApplication::TApplication$base () from /sw/root/lib/libCore.so
#5 0x005d655a in TRint::TRint () from /sw/root/lib/libRint.so
#6 0x0642be58 in TQtWidget::TQtWidget () from /sw/root/lib/libGQt.so
#7 0x08048b5f in main ()

Any idea?

Thanks in advance,
Giulio

Mdaa :frowning:
Ok the first things first.
Which version of ROOT you are using ?

I have to reproduce your problem… Sounds you have quite messy installation.

Can you check your Qt/Root works with the standard ROOT test suite. For example can you run $ROOTSYS/test/benchmarks.C ?
Can you compile and run it under debugger and provide me a call stack ?

Thank you

Mdaa
Ok the first things first.
Which version of ROOT you are using ?

4.04.2

I have to reproduce your problem… Sounds you have quite messy >installation.

Works! I don’t quite understand what I did, but now works… I removed an extra space after “qt” from the rootrc file, could that be it?

Ciao and thanks,
Giulio

Thank you :laughing: