Canvas not showing up in Qt app

I am trying to build a Qt application that uses ROOT for plotting data. I downloaded the latest source and built it with qt enabled (linked against Qt4 instead of Qt5). That part seemed to go fine.

Now I have GUI that includes a TQtWidget and I’m trying to draw on its canvas. I’ve tried a few different examples I found online and the app runs without error but nothing ever shows up inside the TQtWidget; it just stays blank.

Here is my most recent GUI class.

#ifndef ANALYSISFORM_H
#define ANALYSISFORM_H

#include <iostream>

#include "ui_AnalysisForm.h"
#include "TQtWidget.h"
#include "TGraph.h";

class AnalysisForm : public QMainWindow
{
	Q_OBJECT

	public:
	AnalysisForm(QWidget *parent=0);
	virtual ~AnalysisForm();

	bool initialize();

	protected slots:
	void onBtnDrawClicked();
	void onRootCanvasDrawn();

	protected:
	Ui::AnalysisForm *ui;
	TQtWidget *mRootWidget;

	void draw();
};

#endif

and implementation

#include "AnalysisForm.h"

AnalysisForm::AnalysisForm(QWidget *parent) : QMainWindow(parent)
{
	ui = new Ui::AnalysisForm();
	ui->setupUi(this);

	mRootWidget = new TQtWidget(this,"canvas");
	ui->rootWidget = mRootWidget;
}

AnalysisForm::~AnalysisForm()
{
}

bool AnalysisForm::initialize()
{
	connect(ui->btnDraw, SIGNAL(clicked()), this, SLOT(onBtnDrawClicked()) );
	connect(mRootWidget, SIGNAL(CanvasPainted()), this, SLOT(onRootCanvasDrawn()) );

	mRootWidget->GetCanvas()->Update();

	mRootWidget->resize(10,10);
	mRootWidget->resize(300,300);
	mRootWidget->show();

	return true;
}

void AnalysisForm::draw()
{
	std::cout << "drawing" << std::endl;

//	mRootWidget->show();
	mRootWidget->GetCanvas()->cd();  // makes mRootWidget's canvas the current drawing canvas
	mRootWidget->GetCanvas()->Clear();
	mRootWidget->GetCanvas()->SetFillColor(10);
	TGraph *myGraph;
	float x[] = {1,2,3};
	float y[] = {1.5, 3.0, 4.5};
	myGraph = new TGraph(3,x,y);
	myGraph->SetMarkerStyle(20);
	myGraph->Draw("AP");
	mRootWidget->GetCanvas()->Update();
}

//////////////////////// QT slots ////////////////////////////////
void AnalysisForm::onBtnDrawClicked()
{
	draw();
}

void AnalysisForm::onRootCanvasDrawn()
{
	std::cout << "Root is drawn" << std::endl;
}

As you can see, I tried connecting a function to the CanvasPainted event from TQtWidget but that is never getting called. The draw() function is getting called.

My setup:
Windows XP
VS 2010
Qt 4.8.5
Using cmake to create the project

Note that I have NOT built a dictionary for this project. I’m not sure if that is needed or not, especially since I’m not making any new TObjects yet.

The example works for me (likely different Qt and ROOT versions, though) after adding initialize-call and fillings the ui-file gap. Any error messages in the output windows?

I need to reproduce your issue yet to advise.
Please, pay your attention to Root with QT question [quote] . . I’ll be away of all means of electronic communication for a week. Please, do not expect my response before 26th of March. . [/quote] Mean time did you try to build anything from sourceforge.net/p/qtroot/code/HE … tExamples/
Thank you, Valeri

@Valeri: I’m not sure if I’m having the same issue as the other thread. I have no problem building ROOT or my example. It’s just at runtime that I’m not seeing the expected behavior. For the code that you linked to, will that behave different compared to just enabling qt from the source in ROOT trunk?

edit I’m not actually on the latest trunk. I downloaded 5.34.18 production source from the ROOT download page and compiled from there

@tc3t: Sorry, I didn’t realize anyone was going to actually try running it! I’ve attached my complete project, which you can generate with cmake (shouldn’t need to set any variables as long as Qt4 is found and ROOTSYS is set). Does building with this full project also work for you?

Using gDebug=3 I don’t see any errors. Here’s the output:

Info in <TPluginManager::LoadHandlerMacros>: C:\ROOT\install_debug\etc\plugins\T
VirtualPad
Info in <TPluginManager::LoadHandlerMacros>:    plugin macro: C:\ROOT\install_de
bug\etc\plugins\TVirtualPad\P010_TPad.C
Info in <TPluginManager::FindHandler>: found plugin for TPad
Info in <TPluginManager::LoadHandlerMacros>: C:\ROOT\install_debug\etc\plugins\T
VirtualX
Info in <TPluginManager::LoadHandlerMacros>:    plugin macro: C:\ROOT\install_de
bug\etc\plugins\TVirtualX\P010_TGX11.C
Info in <TPluginManager::LoadHandlerMacros>:    plugin macro: C:\ROOT\install_de
bug\etc\plugins\TVirtualX\P020_TGX11TTF.C
Info in <TPluginManager::LoadHandlerMacros>:    plugin macro: C:\ROOT\install_de
bug\etc\plugins\TVirtualX\P030_TGWin32.C
Info in <TPluginManager::LoadHandlerMacros>:    plugin macro: C:\ROOT\install_de
bug\etc\plugins\TVirtualX\P040_TGQt.C
Info in <TPluginManager::LoadHandlerMacros>:    plugin macro: C:\ROOT\install_de
bug\etc\plugins\TVirtualX\P050_TGQuartz.C
Info in <TPluginManager::FindHandler>: found plugin for TGQt
** $Id$ this=02F041A8
Info in <TPluginManager::LoadHandlerMacros>: C:\ROOT\install_debug\etc\plugins\T
GuiFactory
Info in <TPluginManager::LoadHandlerMacros>:    plugin macro: C:\ROOT\install_de
bug\etc\plugins\TGuiFactory\P010_TRootGuiFactory.C
Info in <TPluginManager::LoadHandlerMacros>:    plugin macro: C:\ROOT\install_de
bug\etc\plugins\TGuiFactory\P020_TQtRootGuiFactory.C
Info in <TPluginManager::FindHandler>: found plugin for TQtRootGuiFactory
Info in <TCint::AutoLoad>: loaded dependent library libGQt.dll for class TQtRoot
GuiFactory
Info in <TWinNTSystem::Load>: loading dependent library libMathCore.dll for libr
ary libGui.dll
Info in <TWinNTSystem::Load>: loading dependent library libRIO.dll for library l
ibGui.dll
Info in <TWinNTSystem::Load>: loading dependent library libGraf.dll for library
libGui.dll
Info in <TWinNTSystem::Load>: loading dependent library libGpad.dll for library
libGui.dll
Info in <TWinNTSystem::Load>: loaded library C:\ROOT\install_debug\bin\libGui.dl
l, status 0
Info in <TCint::AutoLoad>: loaded dependent library libGui.dll for class TQtRoot
GuiFactory
Info in <TWinNTSystem::Load>: loading dependent library libGQt.dll for library l
ibQtRoot.dll
Info in <TWinNTSystem::Load>: loading dependent library libGui.dll for library l
ibQtRoot.dll
Info in <TWinNTSystem::Load>: loaded library C:\ROOT\install_debug\bin\libQtRoot
.dll, status 0
Info in <TCint::AutoLoad>: loaded library libQtRoot.dll for class TQtRootGuiFact
ory
Warning in <TCanvas::ResizePad>: hÅ╡☻tqtwidget width changed from 0 to 10

Warning in <TCanvas::ResizePad>: hÅ╡☻tqtwidget height changed from 0 to 10

Warning in <TCanvas::ResizePad>: p╥╡☻canvas width changed from 0 to 10

Warning in <TCanvas::ResizePad>: p╥╡☻canvas height changed from 0 to 10

drawing
Info in <TPluginManager::LoadHandlerMacros>: C:\ROOT\install_debug\etc\plugins\T
VirtualGraphPainter
Info in <TPluginManager::LoadHandlerMacros>:    plugin macro: C:\ROOT\install_de
bug\etc\plugins\TVirtualGraphPainter\P010_TGraphPainter.C
Info in <TPluginManager::FindHandler>: found plugin for TGraphPainter
Info in <TCint::AutoLoad>: loaded dependent library libGpad.dll for class TGraph
Painter
Info in <TCint::AutoLoad>: loaded dependent library libMathCore.dll for class TG
raphPainter
Info in <TCint::AutoLoad>: loaded dependent library libMatrix.dll for class TGra
phPainter
Info in <TCint::AutoLoad>: loaded dependent library libHist.dll for class TGraph
Painter
Info in <TCint::AutoLoad>: loaded dependent library libGraf.dll for class TGraph
Painter
Info in <TWinNTSystem::Load>: loading dependent library libGpad.dll for library
libHistPainter.dll
Info in <TWinNTSystem::Load>: loading dependent library libMathCore.dll for libr
ary libHistPainter.dll
Info in <TWinNTSystem::Load>: loading dependent library libMatrix.dll for librar
y libHistPainter.dll
Info in <TWinNTSystem::Load>: loading dependent library libHist.dll for library
libHistPainter.dll
Info in <TWinNTSystem::Load>: loading dependent library libGraf.dll for library
libHistPainter.dll
Info in <TWinNTSystem::Load>: loaded library C:\ROOT\install_debug\bin\libHistPa
inter.dll, status 0
Info in <TCint::AutoLoad>: loaded library libHistPainter.dll for class TGraphPai
nter
Info in <TPluginManager::LoadHandlerMacros>: C:\ROOT\install_debug\etc\plugins\T
VirtualHistPainter
Info in <TPluginManager::LoadHandlerMacros>:    plugin macro: C:\ROOT\install_de
bug\etc\plugins\TVirtualHistPainter\P010_THistPainter.C
Info in <TPluginManager::FindHandler>: found plugin for THistPainter

Analysis2.zip (3.44 KB)

Using the provided code in an existing project doesn’t work as good, but graph is shown in the member TQtWidget. So there are two TQtWidgets: the one in UI and the other as member. As the first fix candidate try to remove the member and use the one that gets automatically generated through the UI-definition, which is, unlike the member version, properly set in the layout as well.

If that does not work, will anything be shown if you replace the TGraph part by drawing a simple TF1?

Still nothing.

In the constructor I just do

(and comment out the old stuff;

In draw() I now have

void AnalysisForm::draw()
{
	std::cout << "drawing" << std::endl;
	
	TF1 *f1 = new TF1("f1","sin(x)/x",-20,20);
	f1->SetLineWidth(3);
	f1->Draw();
	mRootWidget->GetCanvas()->cd();
	mRootWidget->GetCanvas()->Update();

	mRootWidget->Save("c:\\img.png");
}

which is mostly taken from another example. Note that I’m also trying to save the image but that isn’t working either. Stepping through, in the TQtWidget::Save(…) function there is a section

if (rootFormatFound && c)
  ...
} else if (GetOffScreenBuffer()) {
 ...
}

In my case neither of those conditions are true so the code just skips over everything. Stepping into GetOffScreenBuffer(), it looks like fPixmapID is pointing to 0x0.

I just remembered that my ROOT build is customised, sorry :blush: . But not very big changes: only two added lines in TGQt-class:

to both constructors. I don’t remember why those are there and it should be considered as a hack with no warranty. Also I can’t promise it will help, but perhaps it would be worth checking whether gPtr2VirtualX is nullptr in your case (if you think it’s worth spending any more time on this, that is).

In AnalysisForm::draw, shouldn’t the GetCanvas()->Cd() be before f1->Draw()?

I’ll look into the things you commented on but first I want to ask what plugins you have loaded? Looking again at the projects that Valeri linked to I noticed that he had .rootrc files that loaded extra plugins, which I don’t have.

If I add the line

gPluginMgr->AddHandler("TVirtualX", "qt", "TGQt","GQt", "TGQt(const char*,const char*)");

to my main.cpp I now get a crash when it tries to draw which, right now, seems like progress! Here’s the debug output

Info in <TPluginManager::LoadHandlerMacros>: C:\ROOT\install_debug\etc\plugins\T
VirtualPad
Info in <TPluginManager::LoadHandlerMacros>:    plugin macro: C:\ROOT\install_de
bug\etc\plugins\TVirtualPad\P010_TPad.C
Info in <TPluginManager::FindHandler>: found plugin for TPad
Info in <TPluginManager::LoadHandlerMacros>: C:\ROOT\install_debug\etc\plugins\T
VirtualX
Info in <TPluginManager::LoadHandlerMacros>:    plugin macro: C:\ROOT\install_de
bug\etc\plugins\TVirtualX\P010_TGX11.C
Info in <TPluginManager::LoadHandlerMacros>:    plugin macro: C:\ROOT\install_de
bug\etc\plugins\TVirtualX\P020_TGX11TTF.C
Info in <TPluginManager::LoadHandlerMacros>:    plugin macro: C:\ROOT\install_de
bug\etc\plugins\TVirtualX\P030_TGWin32.C
Info in <TPluginManager::LoadHandlerMacros>:    plugin macro: C:\ROOT\install_de
bug\etc\plugins\TVirtualX\P040_TGQt.C
Info in <TPluginManager::LoadHandlerMacros>:    plugin macro: C:\ROOT\install_de
bug\etc\plugins\TVirtualX\P050_TGQuartz.C
Info in <TPluginManager::FindHandler>: found plugin for TGQt
** $Id$ this=02DB1EB0
Info in <TPluginManager::LoadHandlerMacros>: C:\ROOT\install_debug\etc\plugins\T
GuiFactory
Info in <TPluginManager::LoadHandlerMacros>:    plugin macro: C:\ROOT\install_de
bug\etc\plugins\TGuiFactory\P010_TRootGuiFactory.C
Info in <TPluginManager::LoadHandlerMacros>:    plugin macro: C:\ROOT\install_de
bug\etc\plugins\TGuiFactory\P020_TQtRootGuiFactory.C
Info in <TPluginManager::FindHandler>: did not find plugin for class TGuiFactory
 and uri qtgui
Warning in <TCanvas::ResizePad>:  ♣▒☻tqtwidget width changed from 32000 to 10

Warning in <TCanvas::ResizePad>:  ♣▒☻tqtwidget height changed from 32000 to 10

Warning in <TCanvas::ResizePad>:  ♣▒☻tqtwidget width changed from 32000 to 10

Warning in <TCanvas::ResizePad>:  ♣▒☻tqtwidget height changed from 32000 to 10

Root is drawn
drawing
Info in <TPluginManager::LoadHandlerMacros>: C:\ROOT\install_debug\etc\plugins\T
VirtualPS
Info in <TPluginManager::LoadHandlerMacros>:    plugin macro: C:\ROOT\install_de
bug\etc\plugins\TVirtualPS\P010_TPostScript.C
Info in <TPluginManager::LoadHandlerMacros>:    plugin macro: C:\ROOT\install_de
bug\etc\plugins\TVirtualPS\P020_TSVG.C
Info in <TPluginManager::LoadHandlerMacros>:    plugin macro: C:\ROOT\install_de
bug\etc\plugins\TVirtualPS\P030_TPDF.C
Info in <TPluginManager::LoadHandlerMacros>:    plugin macro: C:\ROOT\install_de
bug\etc\plugins\TVirtualPS\P040_TImageDump.C
Info in <TPluginManager::LoadHandlerMacros>:    plugin macro: C:\ROOT\install_de
bug\etc\plugins\TVirtualPS\P050_TTeXDump.C
Info in <TPluginManager::FindHandler>: found plugin for TImageDump
Info in <TCint::AutoLoad>: loaded dependent library libGraf.dll for class TImage
Dump
Info in <TWinNTSystem::Load>: loading dependent library libGraf.dll for library
libPostscript.dll
Info in <TWinNTSystem::Load>: loaded library C:\ROOT\install_debug\bin\libPostsc
ript.dll, status 0
Info in <TCint::AutoLoad>: loaded library libPostscript.dll for class TImageDump

Info in <TPluginManager::LoadHandlerMacros>: C:\ROOT\install_debug\etc\plugins\T
Image
Info in <TPluginManager::LoadHandlerMacros>:    plugin macro: C:\ROOT\install_de
bug\etc\plugins\TImage\P010_TASImage.C
Info in <TPluginManager::FindHandler>: found plugin for TASImage
Info in <TCint::AutoLoad>: loaded dependent library libMathCore.dll for class TA
SImage
Info in <TCint::AutoLoad>: loaded dependent library libGraf.dll for class TASIma
ge
Info in <TWinNTSystem::Load>: loading dependent library libMathCore.dll for libr
ary libASImage.dll
Info in <TWinNTSystem::Load>: loading dependent library libGraf.dll for library
libASImage.dll
Info in <TWinNTSystem::Load>: loaded library C:\ROOT\install_debug\bin\libASImag
e.dll, status 0
Info in <TCint::AutoLoad>: loaded library libASImage.dll for class TASImage

Does this make sense to you?

With respect to GetCanvas()->cd(), you are probably right. I’m also new to ROOT so have been just moving things around trying to see if some combination of order and voodoo will work.

I haven’t explicitly loaded any plugins and based on a quick look, the only ROOT libs that are explicitly linked are libCore, libGQt and libHist. The list you provided about plugins doesn’t make neither sense nor nonsense to me.

It’s working! I just needed to do more voodoo with the plugins. Basically, it came down to just creating a local .rootrc file (or changing system.rootrc) consisting of

Gui.Backend:	qt
Gui.Factory:	qtgui
Plugin.TGuiFactory:	^qtgui	TQtRootGuiFactory	QtRoot	"TQtRootGuiFactory()

@tc3t I’m curious, do you have that set somewhere?

My system.rootrc was unmodified (Gui.Backend = Gui.Factory = native). I made some experiments with this and here’s the summary (build of QtRoot was not available in the tests):

[ul]
[li]Gui.Backend = native, Gui.Factory = native, unmodified(*) ROOT: no visible graph[/li]
[li]Gui.Backend = native, Gui.Factory = native, modified ROOT: graph visible[/li]
[li]Gui.Backend = qt, Gui.Factory = qt, unmodified ROOT: no visible graph[/li]
[li]Gui.Backend = qt, Gui.Factory = qtgui, unmodified ROOT: graph visible[/li]
[li]Gui.Backend = native, Gui.Factory = native, unmodified ROOT, gEnv->SetValue(“Gui.Backend”, “qt”) and gEnv->SetValue(“Gui.Factory”, “qtgui”) at the beginning of main: graph visible[/li][/ul]

Actually it seemed that string “qtgui” in Gui.Factory can be almost anything beginning with qt as long as it will result in debug message
"Info in TPluginManager::FindHandler: did not find plugin for class TGuiFactory and uri qt". In case of modifed ROOT with native-settings the corresponding message was “Info in TPluginManager::FindHandler: found plugin for TQtRootGuiFactory”.

It’s interesting to note that when the graph is not drawn, there are practically no error messages generated (gDebug=3) although the GUI is obviously not working. Some warnings, “Warning in TCanvas::ResizePad: tqtwidget height changed from 0 to 10”, were generated though.

size=80 i.e. without the hack mentioned earlier[/size]

Is there any indication of what the most “proper” solution is? As in, what will be the most likely to work in the long term going forward?

Given problem like this, speaking of something working let alone on long term sounds like wishful thinking :slight_smile:. But a better response is to be expected from fine when he gets back.