FYI: PyQt example was added recently to the tutorials/pyroot

A small example that demonstrates how one can use PyQt + ROOT env was introduced recently
root.cern.ch/viewvc/trunk/tutori … iew=markup

Thanks to Luca Baldini and Johan BREGEON

Hello,

I’m trying to embed a root canvas in a pyqt application.
Is there a similar example as above we can use with PyQt4 ?

Thanks for any hint !

P.A.

[quote=“pad”]I’m trying to embed a root canvas in a pyqt application.
Is there a similar example as above we can use with PyQt4 ?[/quote]
The example in question contains nothing Qt4 special whatsoever.
I do not see why it can not work assuming one has the QtRoot compiled againts of Qt4. The latest version of QtRoot is recommended. See root.bnl.gov/QtRoot/How2Install4Unix.html for details. One can add the latest version of QtRoot plugin to his / her existing ROOT version.
However, I have neither PyQt4 not PyRoot installed and did not try it myself.

Did you face any real problem? Which one?

Hello Valeri,

Thanks for your fast answer.
I’m first trying to have PyQt and root working together with a standard ROOT distribution (I have Qt 4.3.4 and root 5.20). Maybe it is useless and I need the extension you provide ?

With this set-up what I get is a crash. I use the slightly modified script in attachment (just replacing 'q’t by ‘QtGui’ or QtCore).

localhost[815]:dbtest> python qtexample.py 
TClass::TClass:0: RuntimeWarning: no dictionary for class QObject is available
TClass::TClass:0: RuntimeWarning: no dictionary for class QWidget is available

 *** Break *** segmentation violation
(no debugging symbols found)
Using host libthread_db library "/lib/i686/libthread_db.so.1".

... some traceback lines, then : ...

The program is running.  Quit anyway (and detach it)? (y or n) [answered Y; input not from terminal]
Detaching from program: /proc/11631/exe, process 11631
Traceback (most recent call last):
  File "qtexample.py", line 48, in <module>
    w = window()
  File "qtexample.py", line 31, in __init__
    self.Canvas = ROOT.TQtWidget(sip.voidptr(self.Address).ascobject())
SystemError: problem in C++; program state has been reset

 *** Break *** segmentation violation
(no debugging symbols found)
Using host libthread_db library "/lib/i686/libthread_db.so.1".
Attaching to program: /proc/11631/exe, process 11631
[Thread debugging using libthread_db enabled]
[New Thread -1212959024 (LWP 11631)]
(no debugging symbols found)...done.
(no debugging symbols found)...done.
0xffffe410 in __kernel_vsyscall ()
#1  0xb7bdb02b in waitpid () from /lib/i686/libc.so.6
#2  0xb7b7fb33 in ?? () from /lib/i686/libc.so.6
#3  0xb7b7ff12 in system () from /lib/i686/libc.so.6
#4  0xb7cc881d in system () from /lib/i686/libpthread.so.0
#5  0xb5fcbccd in TUnixSystem::Exec () from /home/delsart/SOFTWARE/root/lib/libCore.so
#6  0xb5fd0f31 in TUnixSystem::StackTrace () from /home/delsart/SOFTWARE/root/lib/libCore.so
#7  0xb5fcfee6 in TUnixSystem::DispatchSignals () from /home/delsart/SOFTWARE/root/lib/libCore.so
#8  0xb5fcffcd in SigHandler () from /home/delsart/SOFTWARE/root/lib/libCore.so
#9  0xb5fc914d in sighandler () from /home/delsart/SOFTWARE/root/lib/libCore.so
#10 <signal handler called>
#11 0xb339e66a in TGQt::End () from /home/delsart/SOFTWARE/root/lib/libGQt.so
#12 0xb33b623e in TQtWidget::~TQtWidget$delete () from /home/delsart/SOFTWARE/root/lib/libGQt.so
#13 0xb6bb6e9c in QObjectPrivate::deleteChildren () from /usr/lib/qt4/lib/libQtCore.so.4
#14 0xb6ddc6be in QWidget::~QWidget$base () from /usr/lib/qt4/lib/libQtGui.so.4
#15 0xb78e653c in ?? () from /usr/lib/python2.5/site-packages/PyQt4/QtGui.so
#16 0xb6bb6e9c in QObjectPrivate::deleteChildren () from /usr/lib/qt4/lib/libQtCore.so.4
#17 0xb6ddc6be in QWidget::~QWidget$base () from /usr/lib/qt4/lib/libQtGui.so.4
#18 0xb70cf26f in QMainWindow::~QMainWindow$base () from /usr/lib/qt4/lib/libQtGui.so.4
#19 0xb76e85ec in ?? () from /usr/lib/python2.5/site-packages/PyQt4/QtGui.so
#20 0xb76e0850 in ?? () from /usr/lib/python2.5/site-packages/PyQt4/QtGui.so
#21 0xb76e08a1 in ?? () from /usr/lib/python2.5/site-packages/PyQt4/QtGui.so
#22 0xb7f0bfde in ?? () from /usr/lib/python2.5/site-packages/sip.so
#23 0x08173dac in ?? ()
#24 0x08173dac in ?? ()
#25 0x00000018 in ?? ()

I’ll try with the extension if necessary.

Cheers,

P.A.
qtexample.py (1.7 KB)

[quote=“pad”]Hello Valeri,

Thanks for your fast answer.
I’m first trying to have PyQt and root working together with a standard ROOT distribution (I have Qt 4.3.4 and root 5.20). Maybe it is useless and I need the extension you provide ?

With this set-up what I get is a crash. I use the slightly modified script in attachment (just replacing 'q’t by ‘QtGui’ or QtCore).

localhost[815]:dbtest> python qtexample.py 
TClass::TClass:0: RuntimeWarning: no dictionary for class QObject is available
TClass::TClass:0: RuntimeWarning: no dictionary for class QWidget is available

 *** Break *** segmentation violation
(no debugging symbols found)
Using host libthread_db library "/lib/i686/libthread_db.so.1".
. . . 

I’ll try with the extension if necessary.

Cheers,

P.A.[/quote]The message is correct and it is not Qt4 related. It says, that there is no ROOT dictionary for Qt class objects. This is correct. Normally we do not create any RootCint dictionary for Qt classes and it WAS NOT needed to run the example in question. This means your problem coming from PyRoot rather from Qt4/QtRoot and you should seek PyRoot guru assistance to clarify the issue.

OO I think I was wrong :blush: !!!

[quote]localhost[815]:dbtest> python qtexample.py
TClass::TClass:0: RuntimeWarning: no dictionary for class QObject is available [/quote] it is just warning.
The problem coming from another direction.
It seems to me since ROOT 5.20 the ROOT application is always started in batch mode and then (at run-time “on fly” ) it is to recognize the graphical layer (X11/Win32/Qt . . .) should be activated by “some” reason.

My guess :unamused: starting PyQt is not :bulb: recognized by ROOT as a reason to activate the graphical layer.

Can you check this?

[quote=“pad”].
Maybe it is useless and I need the extension you provide ?
[/quote]The QtRoot extension and the latest version of Qt-layer is strongly recommended anyway.

[quote]It seems to me since ROOT 5.20 the ROOT application is always started in batch mode and then (at run-time “on fly” ) it is to recognize the graphical layer (X11/Win32/Qt . . .) should be activated by “some” reason.

My guess starting PyQt is not Idea recognized by ROOT as a reason to activate the graphical layer. [/quote]

Please forgive my ignorance but how could I check that … or force a graphic layer to start ?

I’ll try anyway the extension, see if it helps.

Thanks for your advices.

[quote=“pad”]Please forgive my ignorance but how could I check that … or force a graphic layer to start ?[/quote]I am afraid I do not know :blush: the correct answer either.
However, I had to add the clause

void HelloFileBrowser::init() { #if ROOT_VERSION_CODE >= ROOT_VERSION(5,16,0) // Make sure the ROOT graphical layer is initialised. static struct needgraph { needgraph () { TApplication::NeedGraphicsLibs() ; gApplication->InitializeGraphics(); } } needgraph; #endif
root.bnl.gov/QtRoot/root/qtExamp … rowser.cxx
into my Qt examples to make sure the graphics layer is up.

[quote=“pad”]I’ll try anyway the extension, see if it helps.
[/quote] The “extension” may have provided you the more “stable code” and faster (order of magnitide in my tests) rendering. However, one still has to make sure the proper graphics layer is active. May be Fons can explain things better. For example, ROOT does activate the graphics from the TCanvas ctor. Alas, this is not we can do here. We need Qt to be active BEFORE TCanvas ctor is called.
See

[quote=“grep “InitializeGraphics()” $ROOTSYS///src/T*.cxx”]
core/base/src/TApplication.cxx: InitializeGraphics();
core/base/src/TApplication.cxx:void TApplication::InitializeGraphics()
core/base/src/TApplication.cxx: InitializeGraphics();
core/base/src/TBrowser.cxx: gApplication->InitializeGraphics();
core/base/src/TBrowser.cxx: gApplication->InitializeGraphics();
core/base/src/TBrowser.cxx: gApplication->InitializeGraphics();
core/base/src/TBrowser.cxx: gApplication->InitializeGraphics();
core/base/src/TBrowser.cxx: gApplication->InitializeGraphics();
core/base/src/TBrowser.cxx: gApplication->InitializeGraphics();
core/base/src/TBrowser.cxx: gApplication->InitializeGraphics();
core/base/src/TBrowser.cxx: gApplication->InitializeGraphics();
core/base/src/TBrowser.cxx: gApplication->InitializeGraphics();
core/base/src/TColor.cxx: gApplication->InitializeGraphics();
core/base/src/TSystem.cxx: gApplication->InitializeGraphics();
graf3d/eve/src/TEveManager.cxx: gApplication->InitializeGraphics();
net/net/src/TApplicationRemote.cxx: gApplication->InitializeGraphics();
net/net/src/TApplicationRemote.cxx: InitializeGraphics();[/quote]

The method root.cern.ch/root/html/src/TSyst … tml#ZQRsnD
contains the clue:

[code]recCall–;

// will load and initialize graphics libraries if
// TApplication::NeedGraphicsLibs() has been called by a
// library static initializer, only do this when Load() is
// not called recursively
if (recCall == 0 && gApplication)
gApplication->InitializeGraphics();[/code]The method first loads “some” shared lib then initialises the graphics if needed. I.e. the graphics initialized by the order of the third party library. It is not clear what is the correct way to do the same job with no third party shared library above. I did not see another place where the idea is explained but the C++ comment: // will load and initialize graphics libraries if // TApplication::NeedGraphicsLibs() has been called by a // library static initializer, The bug report savannah.cern.ch/bugs/?38382 indicates the problem is not just Qt-related.
root.cern.ch/viewvc/trunk/core/b … 5&r2=24619
root.cern.ch/viewvc/trunk/core/b … x?view=log

CreateGradientColorTable now calls TColor::InitializeColors(); This is needed because is some cases TColor::InitializeColors(); has not been called before.

Hi again,

Mmm. It seems I have anyway a problem with qtroot…
Using the qtroot extension compiled agains qt, and following the instructions to turn qtroot on (root.bnl.gov/QtRoot/QtRoot.html#install), I get the strange behaviour :

localhost[810]:t> root -l
root [0] TBrowser b;
** $Id: TGQt.cxx,v 1.190 2008/08/07 02:09:16 fine Exp $ this=0x83ba7d0
Symbol font family found: Standard Symbols L 
X Error: BadMatch (invalid parameter attributes) 8
  Extension:    156 (RENDER)
  Minor opcode: 4 (RenderCreatePicture)
  Resource id:  0x67

Then, the TBrowser appears as expected but when trying to quit root from it I get crashes :

Root > *** Break *** segmentation violation Using host libthread_db library "/lib/i686/libthread_db.so.1". Attaching to program: /proc/6225/exe, process 6225 [Thread debugging using libthread_db enabled] [New Thread -1227450672 (LWP 6225)] 0xffffe410 in __kernel_vsyscall () #1 0xb6e2f02b in waitpid () from /lib/i686/libc.so.6 #2 0xb6dd3b33 in __gxx_personality_v0 () from /lib/i686/libc.so.6 #3 0xb6dd3f12 in system () from /lib/i686/libc.so.6 #4 0xb6eee81d in system () from /lib/i686/libpthread.so.0 #5 0xb7aa3ccd in TUnixSystem::Exec () from /home/delsart/SOFTWARE/root/lib/libCore.so #6 0xb7aa8f31 in TUnixSystem::StackTrace () from /home/delsart/SOFTWARE/root/lib/libCore.so #7 0xb7aa7ee6 in TUnixSystem::DispatchSignals () from /home/delsart/SOFTWARE/root/lib/libCore.so #8 0xb7aa7fcd in SigHandler () from /home/delsart/SOFTWARE/root/lib/libCore.so #9 0xb7aa114d in sighandler () from /home/delsart/SOFTWARE/root/lib/libCore.so #10 <signal handler called> #11 0xb523ba86 in QApplication::x11ProcessEvent () from /usr/lib/qt4/lib/libQtGui.so.4 #12 0xb526091a in __gxx_personality_v0 () from /usr/lib/qt4/lib/libQtGui.so.4 #13 0xb4e74f3e in QCoreApplication::processEvents () from /usr/lib/qt4/lib/libQtCore.so.4 #14 0xb5c36ed9 in TGQt::NextEvent () from /home/delsart/SOFTWARE/root/lib/libGQt.so #15 0xb5e06329 in TGClient::ProcessOneEvent () from /home/delsart/SOFTWARE/root/lib/libGui.so #16 0xb5e063cd in TGClient::HandleInput () from /home/delsart/SOFTWARE/root/lib/libGui.so #17 0xb5e06400 in TGInputHandler::Notify () from /home/delsart/SOFTWARE/root/lib/libGui.so #18 0xb7aa85f9 in TUnixSystem::DispatchOneEvent () from /home/delsart/SOFTWARE/root/lib/libCore.so #19 0xb7a23781 in TSystem::InnerLoop () from /home/delsart/SOFTWARE/root/lib/libCore.so #20 0xb7a276c1 in TSystem::Run () from /home/delsart/SOFTWARE/root/lib/libCore.so #21 0xb79c36e7 in TApplication::Run () from /home/delsart/SOFTWARE/root/lib/libCore.so #22 0xb7042af0 in TRint::Run () from /home/delsart/SOFTWARE/root/lib/libRint.so #23 0x08048d55 in main ()

Also python seems to have problems : when asking a TBrowser, the window appears but is hanging and stays unresponsive…

Any idea what could be wrong in my set-up ?

Mmmm I am afraid we are coming back :cry: to the issue that was discussed and fixed 2 years ago root.cern.ch/root/roottalk/roottalk07/index.html
Look for “PyQt and PyROOT” thread.
That time we concluded that the reason for the problem was the extra hidden concurrent :bulb: thread within PyROOT implementation. At the time some workaround was introduced (Wim may remind us).
See root.cern.ch/phpBB2/viewtopic.php?t=7489 [quote=“wlav”]. . . . . python starts up a separate thread that calls TSystem::ProcessEvents() . . . [/quote]On the other hand the conclusion was the final application built on the top of PyQt+PyRoot+ QtRoot+Root would be too huge :confused: to be reliable and maintainable.

I’ll try to recall this more carefully tomorrow.

Meantime, the first question first.
Does QtROOT (with no Python) works for you? For example, can you build the Qt tests like this:

cd qtExamples qmake make and execute each test application by visiting each example directory?

[quote=“pad”]I’m trying to embed a root canvas in a pyqt application.
Is there a similar example as above we can use with PyQt4 ?
[/quote]I did not understand whether this example root.cern.ch/viewvc/trunk/tutori … iew=markup works for you with PyQt4 now ?

Hello,

[quote]Meantime, the first question first.
Does QtROOT (with no Python) works for you? For example, can you build the Qt tests like this:
Code:
cd qtExamples
qmake
make
and execute each test application by visiting each example directory?
[/quote]

I could not compile examples having a .ui file. Even specifying QMAKE_UIC=uic3 in the .pro files, then make fails and complains about not finding ‘XXX.h’ file when only ‘XXX.ui.h’ file exists… incompatibility with Qt4 ?

On the other hand HelloCanvas works but I got strange X error messages :

localhost[878]:HelloCanvas> ./HelloCanvas ** $Id: TGQt.cxx,v 1.190 2008/08/07 02:09:16 fine Exp $ this=0x83ba1f8 Symbol font family found: Standard Symbols L X Error: BadDrawable (invalid Pixmap or Window parameter) 9 Major opcode: 55 (X_CreateGC) Resource id: 0x0 X Error: BadDrawable (invalid Pixmap or Window parameter) 9 Major opcode: 55 (X_CreateGC) Resource id: 0x0 X Error: BadGC (invalid GC parameter) 13 Major opcode: 60 (X_FreeGC) Resource id: 0x3200049 X Error: BadGC (invalid GC parameter) 13 Major opcode: 60 (X_FreeGC) Resource id: 0x3200048 X Error: BadDrawable (invalid Pixmap or Window parameter) 9 Major opcode: 55 (X_CreateGC) Resource id: 0x0 X Error: BadDrawable (invalid Pixmap or Window parameter) 9 Major opcode: 55 (X_CreateGC) Resource id: 0x0 X Error: BadGC (invalid GC parameter) 13 Major opcode: 60 (X_FreeGC) Resource id: 0x320004d X Error: BadGC (invalid GC parameter) 13 Major opcode: 60 (X_FreeGC) Resource id: 0x320004c

Concerning :

Yes using the qtroot extension with proper set-up it works but :

  • same X errors as above
  • when clicking on quit, the window closes but the process hang and does not terminate

[quote=“pad”]localhost[878]:HelloCanvas> ./HelloCanvas ** $Id: TGQt.cxx,v 1.190 2008/08/07 02:09:16 fine Exp $ this=0x83ba1f8 Symbol font family found: Standard Symbols L [/quote]The last revision of TGQt is v. 1.204 2008/10/10. Yours is " 1.190 2008/08/07 ". It is “14 revisions” and “2 months” old. Can you try the latest one? By the way, I use Qt 4.4.x now. I do not test my application against Qt 4.3.x anymore. [quote=“pad”][quote=“fine”]I did not understand whether this example … works for you with PyQt4 now ?[/quote]Yes using the qtroot extension with proper set-up it works[/quote]Great :smiley: . Thank you. [quote=“pad”] but :

  • same X errors as above
  • when clicking on quit, the window closes but the process hang and does not terminate[/quote]I did see the “X errors” with my previous QtRoot revisions. I do not see it now :unamused: . Please, update your version to see whether “X error” persists with the last version.
    What about “hanging”. I think this is the same :bulb: problem we discovered 2 years ago. PyROOT created the extra thread making the entire Python script to be the multithreaded application with the extra event loop. That screw things. This was eliminated and the issue was fixed . I still have :blush: to find out the exact receipt. In my mind some line in PyRoot implementation had to be commented out. Sorry, I do not use PyROOT myself and relies on the PyROOT users experience.

[quote=“pad”]I could not compile examples having a .ui file. Even specifying QMAKE_UIC=uic3 in the .pro files, then make fails and complains about not finding ‘XXX.h’ file when only ‘XXX.ui.h’ file exists… incompatibility with Qt4 ?[/quote]You should update your local version of QtRoot. The examples were adjusted for Qt4 recently.

I’ve found :laughing:
lists.bnl.gov/pipermail/qt-root … hread.html
the old discussion in my E-mail archive. Here you are

[quote=“Johan Bregeon”]

[code]> -----Original Message-----

From: Johan Bregeon [mailto:johan.bregeon@pi.infn.it]
Sent: Friday, January 19, 2007 2:13 PM
To: Fine, Valeri; Claus, Richard; kocian@slac.stanford.edu;
WLavrijsen@lbl.gov; Luca Baldini
Subject: Re: [Qt-root-l] [ROOT] RE: PyQt and PyROOT

Hello Valeri,
I added the .rootrc and added the debug mode.
Then launch the simple gWindow.py example I sent you sometimes…
and the script just hanged up here :

Which: libvectorDict.so = /usr/local/root/v5.14.00/lib/libvectorDict.so
Info in TUnixSystem::Load: loaded library
/usr/local/root/v5.14.00/lib/libvectorDict.so, status 0

So I thought that did not help…but then I got to hack the ROOT.py as
you suggested :
# root thread, if needed, to prevent GUIs from starving, as needed
if not self.keeppolling and not _root.gROOT.IsBatch():
import threading
#self.dict[ ‘keeppolling’ ] = 1
#self.dict[ ‘thread’ ] =
# threading.Thread( None, _processRootEvents, None, ( self, ) )
#self.thread.setDaemon( 1 )
print “cacca”
#self.thread.start()

And then I launched again the gWindow.py example…and it works now !!!
. . .
. . .
Anyway, the thing is to understand why the thread thrown by ROOT.py does
not behave well. Maybe one solution could just be not to create that
thread when using ROOT.py inside a PyQt application as it seems useless…
For now, we gonna keep the modify ROOT.py and try to go further, may be
switch to PyQt4…
[/code]

[/quote]I’ve sent E-mail to Johan Bregeon asking him to visit this thread.

Hello,

So I confirm that when doing things right :

  • latest version of qtRoot extension
  • turn it on in rootrc

the python example works (and rest of examples also works).

However it is impossible to simply use pyroot interactively :

[code]>>> import ROOT

h = ROOT.TH1F(“hh”,“hh”,100,0,45)
** Id: TGQt.cxx,v 1.204 2008/10/10 00:01:35 fine Exp this=0x8607f40
Symbol font family found: Standard Symbols L
X Error: BadMatch (invalid parameter attributes) 8
Extension: 156 (RENDER)
Minor opcode: 4 (RenderCreatePicture)
Resource id: 0x67
[h.Fill((i**2) % 45) for i in range(600) ]

h.Draw()
[/code]

There is an other X Error + the Draw() command produce an unusable/unresponsive window (same thing when trying to produce a TBrowser() )…

Cheers,

P.A.

I do not see how you activated the so-called "event-loop"
You need to do that either PyROOT or PyQt4 way:
See: root.cern.ch/root/html/TApplicat … cation:Run and
root.cern.ch/viewvc/trunk/tutori … iew=markup

if __name__ == '__main__': application = qt.qApp terminator = ROOT.TQtRootSlot.CintSlot() termAddress = sip.wrapinstance(ROOT.AddressOf(terminator)[0],qt.QObject) qt.QObject.connect(application, qt.SIGNAL("lastWindowClosed()"),termAddress ,qt.SLOT("Terminate()")) w = window() w.show() ROOT.gApplication.Run(1) print 'Bye forever!' or
doc.trolltech.com/4.4/qapplication.html#exec
See for example zetcode.com/tutorials/pyqt4/firstprograms/

[code]#!/usr/bin/python

tooltip.py

import sys
from PyQt4 import QtGui
from PyQt4 import QtCore

class Tooltip(QtGui.QWidget):
def init(self, parent=None):
QtGui.QWidget.init(self, parent)

    self.setGeometry(300, 300, 250, 150)
    self.setWindowTitle('Tooltip')

    self.setToolTip('This is a <b>QWidget</b> widget')
    QtGui.QToolTip.setFont(QtGui.QFont('OldEnglish', 10))

app = QtGui.QApplication(sys.argv)
tooltip = Tooltip()
tooltip.show()
app.exec_()[/code]To see what I mean try to remove the last statement app.exec_() from the pure PyQt4 example (there is neither PyROOt nor QtRoot there)