PDA

View Full Version : Problem with mixed statically/shared Qt



WinchellChung
18th June 2007, 19:52
I have a simple Qt app that works like a charm when I compile and link it using shared Qt in DLLs, but when I compile and link with a statically linked Qt it crashes and burns with a the error

QWidget: Must construct a QApplication before QPaintDevice

I'm using Qt 4.2.3 commercial, compiling with MS Visual Studio 2005, on the Windows platform.

The problem appears to lie within another DLL created by an outside contractor, call it DLL-X. It uses Qt, but is compiled with Qt shared. It defines some custom features for a custom widget. Anyway the problem goes away if DLL-X is not used.

Some background: after my ramshackle attempt to create a statically linked version of Qt, when I compile and link my own app with it, I have to ensure that the project's configuration properties|linker|input|additional dependencies includes QtCored.lib. When linking as shared, I have to include QtCored4.lib

So I run the app, and it crashes with the above bug. Looking at the call stack, my QMainWindow's constructor is called. It does a standard ui.setupUi(this).

In ui.setupUi(this), it creates an instance of the X-DLL widget. The widget inherits from QFrame as well as QWidget. Here I notices that it calls the QFrame constructor from inside QtGuid4.dll, not QtGuid.dll.

The QFrame constructor invokes the QFramePrivate constructor. The QFramePrivate constructor invokes the QWidgetPrivate constructor.

And the first thing the QWidgetPrivate constructor does is

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

with the qApp macro returning a value of "False", even though a QApplication has been created in the main() function.

Is there any easy way of having the qApp macro detecting the QApplication, or am I going to have to try and compile X-DLL as a statically linked library?

kernel_panic
21st June 2007, 12:17
maybe it could be easier if you give us some code.

anyway, if "QWidget: Must construct a QApplication before a QPaintDevice" is sent, it mostly means, that you didn't construct a QApplication.

did you write a main file with contents similar to this:


#include <QApplication>
#include "MainWindow.h"


int main(int argc, char *argv[])
{
int exec;

QApplication app(argc, argv);


MainWindow mainWindow("Test");
mainWindow.show();

exec = app.exec();
return exec;
}


sry for my bad english!

WinchellChung
21st June 2007, 18:04
Thank you, I did have main file similar to that.

I managed to solve the problem. As I feared, it was because I was creating an application with Qt statically linked into it, and the application was using a Dll which was using Qt as a shared library.

So the Dll tried to create some Qt widgets, and the shared Qt library could not find a running instance of a Qt application (because it was hidden in the statically linked main application).

Because I was in a hurry, I solved the problem by copying all the code in the Dll into my main application, which fixed the problem. A very ugly quick-and-dirty solution, but it worked.