[QtRoot] TQtWidget::Refresh() causes segmentation fault

Dear all,

I’m building a Qt application that’s trying to use the TQtWidget class to embed some TCanvases. While trying to get the first one running, I noticed that I was getting a seg fault whenever the Canvas goes to refresh itself.

I’m running Root v5.30 with Qt 4.7.3 on Ubuntu 11.10, and am compiling from the terminal:

qmake-qt4 make

I get no problems from compilation, only during execution. Sadly, I don’t get any useful information from the crash, other than the segfault. A stripped down example (which exhibits the same error) uses the following code:

[code]#include “MainWindow.h”
#include “ui_MainWindow.h”

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow),
g()
{
ui->setupUi(this);
w = new TQtWidget(this, “MyWidget”);
w->resize(800,600);
w->cd();

Int_t x[5], y[5];
for(int i=0; i<5; i++)
{
    x[i] = i; y[i]=i*i;
}

g->DrawGraph(5, x, y);
w->Refresh();

update();

}

MainWindow::~MainWindow()
{
delete ui;
delete w;
delete g;
}
[/code]

Any and all help would be appreciated.

Can you upload your project files ?

Hello Fine,

Absolutely. It’s available here: http://cl.ly/HzBF

Hi
Thank you very much for you project.
The bad news :frowning: Your short project project has several issues, usage of the zero pointer, double deletion of the died objects , race conditions, incorrect use of the Qt Designer etc. #-o

The good news :bulb: : it is easy to fix :smiley: .

Please, find your fixed project attached. I check it on MS Windows and on CERN LXPLUS as well.
Compare it with your original version. Do not hesitate asking me the further questions. I am willing to elaborate if needed.

The working version of your code looks like this:

[code]#include “MainWindow.h”
#include “ui_MainWindow.h”

MainWindow::MainWindow(QWidget parent) :
QMainWindow(parent),
ui(new Ui::MainWindow),
g()
{
ui->setupUi(this);
Int_t x[5], y[5];
for(int i=0; i<5; i++)
{
x[i] = i; y[i]=i
i;
}
g = new TGraph(sizeof(x)/sizeof(float),x,y);
ui->widget->cd();
g->Draw();
}
MainWindow::~MainWindow()
{ }
[/code]

Even though this version does work, it is NOT [-X recommended to use the rendering operation ( including the ROOT methods cd() and Draw() ) from within the widget ctor. The dedicated Qt slot to create the ROOT object is more reliable approach to create the complex Qt widgets.

The new version of the project uses the Qt Designer promote feature to add the “TQtWidget *widget” to UI

(See qt-project.org/doc/qt-4.8/design … ng-widgets for details) .
Qt framework takes care about all widgets it creates. This is why one must not [-o< delete it at all.
The TQtWigdet contains the “embedded” ROOT TCanvas. The later deletes the objects it rendered.
So:

  1. "QMainWindow dtor destroys ui;
  2. ui destroys all children including the TQtWigdet *widget";
  3. TQtWidget::~TQtWidget deletes the embedded TCanvas
  4. TCanvas deletes all objects ( not always though, see ROOT docs for details ) including TGraph

In addition you are recommended to install ( follow to “Complement the existent ROOT installation with QtRoot plugin” qtroot.svn.sourceforge.net/viewv … tExamples/ ) which is the collection of HelloWorld-level working QtRoot applications addressing all QtRoot use cases I have encountered.

Check my recent post HelloCanvas on Qt app using ROOT with VC2010&Qt 4.8.1 also.
RootTry1.0.0.tar.gz (2.21 KB)

Thanks very much for the info on Qt, and coding practices therein. That actually makes the whole thing worth while, regardless of whether I fix this.

I implemented all the changes you suggested, and the changes have indeed produced a properly rendered TGraph – but only on every second execution of the program for some reason. The problem (a seg-fault) persists on the first execution, and then it works properly (beautifully, as a matter of fact) on the second execution, and fails again on the third, and so on.

I have no idea what that’s about, but it may be related to the system I’m running – so I’m going to try it on another development system when I get the opportunity. Hopefully it’s just a problem with the system and I can get back to development.

Cheers!

[quote=“arobicha”] … it works properly (beautifully, as a matter of fact) …[/quote] :smiley:

[quote=“arobicha”]Thanks very much for the info on Qt, and coding practices therein. That actually makes the whole thing worth while, regardless of whether I fix this.
I implemented all the changes you suggested,[/quote]Did you follow my[quote=“fine”]In addition you are recommended to install ( follow to "Complement the existent ROOT installation with QtRoot plugin qtroot.svn.sourceforge.net/viewv … tExamples/ ) which is the collection of HelloWorld-level working QtRoot applications addressing all QtRoot use cases I have encountered.[/quote] to build your application against of that plugin?[quote=“arobicha”]it works properly … on the second execution.[/quote] #-o May I ask you [-o< to try what I recommended to see whether it makes any difference. It should take you 5-10 min to complete.

Also may I ask you to try with your existing system the slightly different version of the MainWindows as follows:[code]#include “MainWindow.h”
#include “ui_MainWindow.h”
#include “TList.h”

MainWindow::MainWindow(QWidget parent) :
QMainWindow(parent),
ui(new Ui::MainWindow),
g()
{
ui->setupUi(this);
Int_t x[5], y[5];
for(int i=0; i<5; i++)
{
x[i] = i; y[i]=i
i;
}
g = new TGraph(sizeof(x)/sizeof(float),x,y);
g->SetBit(kMustCleanup);
TPad *p = ui->widget->GetCanvas();
p->GetListOfPrimitives()->Add(g);
}
MainWindow::~MainWindow()
{ }[/code]to remove the ROOT “rendering” from the widget ctor ( it is redundant anyway. So your application will work faster )
Check this post Compile root with Qt but without dependence on libQtWebKit too