You are not logged in.

1

Friday, April 6th 2012, 8:36am

Receiving the error: "QWidget: Must construct a QApplication before a QPaintDevice"

Hello, I've been trying to integrate OSG and Qt, and I've been trying to implement the example found here:
http://www.openscenegraph.org/svn/osg/Op…apterWidget.cpp

Unfortunately, upon execution of the example code, I receive the runtime error: "QWidget: Must construct a QApplication before a QPaintDevice", which causes the application to close down.

I've removed as much of the code as possible, leaving only the following relevant parts (there's still some more in the code, but none of it is ever reached, nor did commenting out parts make any difference):

Source code

1
2
3
4
5
6
7
8
9
10
11
12
#include 
#include "CompositeViewerQT.h"
#include 

using namespace std;
int main( int argc, char **argv ){
	cout << "1";
 QApplication app(argc, argv);
cout << "2"; 
	CompositeViewerQT viewer;
 cout << "3";
}



And two classes:

Source code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include "AdapterWidget.h"
#include 
#include 
#include 

using namespace std;

class CompositeViewerQT: public osgViewer::CompositeViewer, public AdapterWidget{

public: 
 CompositeViewerQT(QWidget * parent = 0, const QGLWidget * shareWidget = 0, WindowFlags f = 0): AdapterWidget( parent, shareWidget, f )        {	
 cout << "a";	
}
}



Source code

1
2
3
4
5
6
7
8
9
10
11
#include #include #include 

using namespace std;

class AdapterWidget : public QGLWidget	{

 public:	
 AdapterWidget( QWidget * parent = 0, const QGLWidget * shareWidget = 0, WindowFlags f = 0 ):QGLWidget(parent, shareWidget, f) {	
 cout << "b"; 
	}
}



After execution I get the output "12". 3,a and b are not printed. No other methods are reached either.
As I am creating the QApplication, in accordance with how it seems to be done in every example, and since I'm using a example which I suppose should work, this issue is confusing me greatly. Does anyone have an idea why this error could be occuring, and more importantly how to stop it?

It might be important to note that I dod not generate this project as a Qt project. Rather it was an OSG project, which had been converted into Qt by changing dependencies and some values in the project files.

Some funcitonality of Qt has been shown to work in this project, the following code did manage to bring an empty screen forth.

Source code

1
2
QWidget window;
window.show();

This post has been edited 1 times, last edit by "Gix" (Apr 6th 2012, 8:41am)


2

Thursday, April 12th 2012, 9:54am

The issue had not been resolved yet, does anyone have any ideas?

3

Thursday, April 12th 2012, 12:24pm

well, the error is simple - a QWidget/paintdevice is constructed before QApplication is - this can happen by using static or global variables. You will have to search the code for this. We can't do anything unless you give the complete (minimal, please!) example.
If you have a problem, CUT and PASTE your code. Do not retype or simplify it. Give a COMPLETE and COMPILABLE example of your problem. Otherwise we are all guessing the problem from a fabrication where relevant details are often missing.

4

Thursday, April 12th 2012, 12:56pm

This is the complete code. I have had everything else commented out, including the parts which I had left in originally because they did not seem to matter. For the complete code of the example (which did not function either because of the same error), visit the link posted in the original comment: http://www.openscenegraph.org/svn/osg/Op…apterWidget.cpp

Besides what is shown being the complete code, the execution actually goes past:

Source code

1
QApplication app(argc, argv);



As "12" is printed before the crash. If the error would be thrown because of a static variable attempting to make a QPaintDevice before doing "QApplication app(argc, argv);"
, then neither "1" nor "2" should be printed.



EDIT:

It seems the includes of the original post have dissapeared, which may be the cause of confusion. The includes as they are now are:

In AdapterWidget.h:

Source code

1
2
#include <osgViewer/Viewer>#include <QtCore/QString>#include <QtCore/QTimer>#include <QtGui/QKeyEvent>#include <QtGui/QApplication>#include <QtOpenGL/QGLWidget>#include <osgViewer/CompositeViewer>#include <iostream>
using Qt::WindowFlags;



In CompositeViewer.h

Source code

1
#include <osgViewer/Viewer>#include <QtCore/QString>#include <QtCore/QTimer>#include <QtGui/QKeyEvent>#include <QtGui/QApplication>#include <QtOpenGL/QGLWidget>#include <osgViewer/CompositeViewer>#include "AdapterWidget.h"using Qt::WindowFlags;



In main.cpp

Source code

1
2
#include <iostream>#include <osgUtil/Optimizer>#include <osgDB/ReadFile>#include <osgSim/OverlayNode>#include <osgSim/SphereSegment>#include <osgSim/ScalarsToColors>#include <osgSim/ColorRange>#include <osgSim/ScalarBar>#include <osg/Material>#include <osg/Geode>#include <osg/BlendFunc>#include <osg/Depth>#include <osg/Projection>#include <osg/PolygonOffset>#include <osg/MatrixTransform>#include <osg/Camera>#include <osg/FrontFace>#include <osg/Fog>#include <osg/PolygonMode>#include <osgText/Text>#include <osgGA/TrackballManipulator>#include <osgGA/FlightManipulator>#include <osgGA/StateSetManipulator>#include <osgGA/NodeTrackerManipulator>#include <osgViewer/ViewerEventHandlers>#include <osg/ShapeDrawable>#include <osgDB/FileUtils>#include <osgDB/fstream>#include <osgDB/ReadFile>#include <osgViewer/CompositeViewer>#include <osg/io_utils>#include <QtGui/QApplication>#include <QtGui/QGridLayout>#include <osgQt/GraphicsWindowQt>#include "QtGui/qtextlist.h"#include "CompositeViewerQT.h"
using namespace std; 



The irrelevant ones for the code I'm testing now have all been commented out at some point.

This post has been edited 1 times, last edit by "Gix" (Apr 12th 2012, 1:05pm)


5

Thursday, April 12th 2012, 2:40pm

yes, fair point about "1" and "2" showing. Looks like it's time to get the debugger out and step into the code.


I also found this:
"we strongly recommend that all subclasses of QObject use the Q_OBJECT macro"
http://doc.qt.nokia.com/4.7-snapshot/metaobjects.html


maybe you should adjust some headers accordingly...
If you have a problem, CUT and PASTE your code. Do not retype or simplify it. Give a COMPLETE and COMPILABLE example of your problem. Otherwise we are all guessing the problem from a fabrication where relevant details are often missing.

6

Friday, April 13th 2012, 8:45am

I stepped into the code and couldn't find anything of particular note.

The code throwing the error is:

Source code

1
    if (!qApp) {        qFatal("QWidget: Must construct a QApplication before a QPaintDevice");        return;    }



qApp is a value set with the following code:

Source code

1
#define qApp (static_cast<QApplication *>(QCoreApplication::instance()))



QCoreApplication::instance() cointains the following:


Source code

1
{ return self; }



self is a static QCoreApplication* variable within qcoreapplication.h

Self should be set within the init method of QCoreApplication:

Source code

1
 QCoreApplication::self = this;



The init method is called in the following two two constructors of QCoreApplication:

Source code

1
QCoreApplication::QCoreApplication(QCoreApplicationPrivate &p)    : QObject(p, 0)



Source code

1
QCoreApplication::QCoreApplication(int &argc, char **argv)    : QObject(*new QCoreApplicationPrivate(argc, argv))




It seems the second of those should be called when QApplication is created.

Unfortunately, I was unable to use the debugger to get into the constructor of QApplication for some reason (could that be another symptom of the same problem?), going into the creation of the widget however showed no anomalies. The qApp variable just never had been filled somehow.

I might take a look into the Q_OBJECT macro you mentioned, however I don't really expect any changes as QT examples in other projects worked just fine without that.

7

Friday, April 13th 2012, 9:20am

if you are on linux

try
ldd your_executable
to verify coherence of found libraries

you can also remove the creation of th widget to allow app.exec(), launch your application and try
cat /proc/xxxx/ maps
where xxxx is the pid of your running application

8

Friday, April 13th 2012, 9:30am

are you using libraries that have been built with a different version of Qt than what you are using?

You say that this is fine

Source code

1
2
QApplication app;
app.exec();


but this isnt

Source code

1
2
3
QApplication app(argc, argv);
CompositeViewerQT viewer;
app.exec();


Therefore you need to step into CompositeViewer ctor (and its base classes ctors)

It should also be easy to attach at the point of the assert simply by clicking 'retry' when the assert happens?
If you have a problem, CUT and PASTE your code. Do not retype or simplify it. Give a COMPLETE and COMPILABLE example of your problem. Otherwise we are all guessing the problem from a fabrication where relevant details are often missing.

9

Friday, April 13th 2012, 10:03am

if you are on linux

try
ldd your_executable
to verify coherence of found libraries

you can also remove the creation of th widget to allow app.exec(), launch your application and try
cat /proc/xxxx/ maps
where xxxx is the pid of your running application
I'm afraid I'm on Windows (xp) right now., are there any similar coherence checks that can be done on Windows?
are you using libraries that have been built with a different version of Qt than what you are using?
As far as I'm aware the libraries are all built with the same version. The install had been done by someone else who I can't contact anymore, so I'm not 100% sure, but as far as I've heard and from what I can see, only one version of Qt has ever been installed (4.7.3). All Qt libraries are also found within the source folders of this Qt version. After many attempts with just the libraries which I expected to be needed, I currently have every single .lib found within Qt imported, just to be sure I wasn't missing anything.

Quoted

You say that this is fine

Source code

1
2
QApplication app;
app.exec();


but this isnt

Source code

1
2
3
QApplication app(argc, argv);
CompositeViewerQT viewer;
app.exec();


And yes, your first code works fine. It doesn't really do anything besides show the couts, but there are no errors. There are no errors either if I remove the inheritance of AdapterWidget (and by extension CompositeViewerQT) from QGLWidget. In fact, when I remove that inheritance, the CompositeViewer can be used for OpenSceneGraph and it functions perfectly, there just isn't any Qt involved then (the QApplication isn't even used)


Quoted

Therefore you need to step into CompositeViewer ctor (and its base classes ctors)


The reason why the error is thrown is not because of the constructor of the baseclass of the viewer itself, it is because the qApp variable is never set when the QApplication is created while it should be (or it is set but removed again before the CompositeViewerQT is created). The .exec() apparantly doesn't require that variable to be set. I went through the constructor of the base classes of CompositeViewerQT. but did not find any strage code, not anything that would clear qApp at least. I stil can't seem to go through the code behind the QApplication constructor with the debugger.

Quoted

It should also be easy to attach at the point of the assert simply by clicking 'retry' when the assert happens?


I didn't really understand this, could you clarify? I don't know what an assert is, nor am I aware of any 'retry' buttons.



EDIT:

Actually, update: QCoreApplication::instance() when called from the main method actually contains the correct pointer So the QApplication constructor is doing something right at least.

This post has been edited 1 times, last edit by "Gix" (Apr 13th 2012, 10:22am)


10

Friday, April 13th 2012, 10:21am

seems me depends.exe is for this, "google for it"

11

Friday, April 13th 2012, 1:11pm

in your first post you say that you see "12". Therefore the Qapp ctor completes successfully. Why are you trying to debug here?


What is your o/s that you are developing on? windows/linux/... ?

On windows when a program asserts, it will show a dialog and allow you to retry/ignore/abort if debug information is available.
You are building your app in debug, right?

asserts are commonly used in programs to ensure correctness - you really do need to know about these and should use them frequently.
http://www.cplusplus.com/reference/clibrary/cassert/assert/

It is my belief that "QWidget: Must construct a QApplication before a QPaintDevice" is programmed as an assert, not an exception (I could be wrong...)

I have also seen that some of Qt libraries do not support static linking. Are you linking statically or dynamically?
If you have a problem, CUT and PASTE your code. Do not retype or simplify it. Give a COMPLETE and COMPILABLE example of your problem. Otherwise we are all guessing the problem from a fabrication where relevant details are often missing.

12

Friday, April 13th 2012, 1:16pm

Ok it seems the problem is fixed.
Instead of trying to add more libraries I figured I might try to remove some, and eventually at one point the program got through to the next part.
As it turns out, it's possible to use QtCored4.lib and QtCore4.lib as well as QtGuid4.lib and QtGui4.lib and QtOpenGLd4.lib and QtOpenGL4.lib. However, I had to pick either 3 with a 'd' in the name, or 3 without. Any other combination or importing all 6 gave me that error.

Strangely enough, changing this somehow messed up a different part of the program which was unrelated and had been functioning fine since the start . Currently getting access violation writing errors(even if I remove all the altered code), so if this is the true solution has yet to be seen.

13

Friday, April 13th 2012, 1:44pm

you should show your .pro file(s)

14

Friday, April 13th 2012, 3:52pm

oh dear god. Yes, doing ridiculous things like linking with two versions of the same library in debug/release and mix-matching between release/debug can do silly things X( X(
If you have a problem, CUT and PASTE your code. Do not retype or simplify it. Give a COMPLETE and COMPILABLE example of your problem. Otherwise we are all guessing the problem from a fabrication where relevant details are often missing.