[QScintilla] "QWidget: Must construct a QApplication before a QWidget" and crash in debug on windows

Cedric Perthuis cedric.perthuis at gmail.com
Wed Nov 30 07:58:09 GMT 2016


Hi,

Many people have noticed online for few years that:
#1 qscintilla requires the debug/release configurations to match between
qscintilla and Qt, else you're getting the error "QWidget: Must construct a
QApplication before a QWidget" during the construction of QsciScintilla.
#2 qscinitilla release + Qt release + debug user application was crashing
in the qscintilla destructor.


So this forces people to use Qt debug in their debug application which has
pretty bad performance impact. it works on small programs, but on bigger
application, especially graphics applications, you don't want to suffer
100s of milliseconds each time the Qt layout changes.
So asking people to switch to Qt debug isn't a solution since Qt release
works perfectly fine in a debug application.

I haven't investigate problem #2 yet, but it sounds like a common issue
with using STL streams. STL streams in a DLL requires the app to use the
same CRT, especially when the dll was built with a different version of
visual or a different compiler patch. Maya plugins have suffered from that
issue in the past.

I looked at problem #1.
I used qscintilla debug, user app debug and Qt release.

I got:

Error: QWidget: Must construct a QApplication before a QWidget

Callstack:
  Qt5Cored.dll!qt_message_fatal(QtMsgType __formal, const
QMessageLogContext & context, const QString & message) Line 1673 C++
  Qt5Cored.dll!QMessageLogger::fatal(const char * msg, ...) Line 793 C++
  Qt5Widgetsd.dll!QWidgetPrivate::QWidgetPrivate(int version) Line 302 C++
  Qt5Widgetsd.dll!QFramePrivate::QFramePrivate() Line 61 C++
  Qt5Widgetsd.dll!QAbstractScrollAreaPrivate::QAbstractScrollAreaPrivate()
Line 174 C++
  Qt5Widgetsd.dll!QAbstractScrollArea::QAbstractScrollArea(QWidget *
parent) Line 567 C++
> qscintilla2d.dll!QsciScintillaBase::QsciScintillaBase(QWidget * parent)
Line 87 C++
  qscintilla2d.dll!QsciScintilla::QsciScintilla(QWidget * parent) Line 63
C++


In the Qt source, the error "QWidget: Must construct a QApplication before
a QWidget" is returned if qApp is NULL.
qApp is call to an instance() function which points to the
"static QCoreApplication *self;" in the Qt class QCoreApplication.

This should not be possible for this static to be NULL if the QApplication
has been initialized.
It's true, as long as it's the same qApp we're talking about.
And as we can see in the callstack the NULL qApp is in QtCore5d.dll , the
debug library, while I was supposedly using the release Qt dlls.

I checked the list of loaded modules and sure enough, there were 2 versions
of Qt loaded:
List of modules loaded:
qscintilla2d.dll
Qt5Core.dll
  Qt5Cored.dll
Qt5Gui.dll
Qt5Guid.dll
Qt5PrintSupportd.dll
Qt5Widgets.dll
Qt5Widgetsd.dll

The qscintilla dll is probably implicitely linking with Qt debug dlls in
debug. And that's the problem.

I think it would be nice to mention this potential issue in big characters
on the main page in the windows section, as most users will use Qt release
for their debug application.
I also think, the makefile should be changed with the addition of a new
configuration which is qscintilla debug linked with qt release.
And that probably should be the default.

Thanks,
Cedric.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://www.riverbankcomputing.com/pipermail/qscintilla/attachments/20161129/8247a596/attachment.html>


More information about the QScintilla mailing list