"Must construct a QApplication before a QWidget" error, but only on Windows builds? - c++

I am working on a CMAKE C++ project which uses the QT Libraries. (For me, 5.15.3, for others 5.12.x)
In this project, there is a class Vtk3DViewer : public QWidget. In its constructor, it tries to create one of its member variables, which is of type QVTKOpenGLNativeWidget. This is from the VTK libraries. (Located in include\vtk-9.2\QVTKOpenGLNativeWidget.h)
For me, this new QVTKOpenGLNativeWidget() call within the constructor of my QWidget fails with the following error:
"Must construct a QApplication before a QWidget"
But that's just it, we do create a QApplication in main() well before this point. And this only happens on Windows. Linux builds appear to not have any issue.
Switching from Debug to RelWithDebugInfo moves the error - making it happen much earlier and on creating a QToolBarExt instead.
Why is this happening, and how do I fix it?
Here is an example of main():
int main(int argc, char* argv[])
{
// Set info for settings & registry
QApplication::setOrganizationName(COMPANY_NAME);
QApplication::setOrganizationDomain(COMPANY_DOMAIN);
QApplication::setApplicationName(APP_NAME);
// Set up for software-based backend for VTK
QApplication::setAttribute(Qt::AA_UseOpenGLES);
QApplication a(argc, argv);
a.setWindowIcon(QIcon(":/main-window/favicon.ico"));
// Instantiate singletons
TaskExecutionManager::getInstance(); // Instantiate the task manager
DataDispatcher::getInstance();
// Create main window with default size
MainWindow w;
w.show();
// Start application event loop
return a.exec();
}
Then the main window's constructor calls:
void MainWindow::initializeMainWindow(Ui::MainWindow* ui)
{
this->setDockOptions(AnimatedDocks | AllowNestedDocks | AllowTabbedDocks | GroupedDragging);
// Main toolbar
m_topToolBar = new QToolBarExt(this); // This causes a "Must construct a QApplication before a QWidget" error
}

The issue was that VTK was built in RELEASE, while our project was built in DEBUG.
(I did not see this as an issue, since we would never need to step into/debug VTK's code)
It appears this cryptic/incorrect error message will appear under these circumstances. Ensuring VTK and the project it includes are compiled the same way fixes it.

Related

QTCreator 5.0.2, parallel run of two window, C++

I went throught suggested "questions" about my problem. However neither does not solve it.
I program two windows. The second window is opening from first window. I need active the both windows, however to start the first window(MainWindow) I use:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.setWindowModality(Qt::NonModal);
return a.exec();
}
As was mentioned, the second window is started from pushButton, which is situated in first window(MainWindow) by same way.
void MainWindow::on_pushButton_2_clicked()
{
Graphics gr;
gr.setWindowModality(Qt::NonModal);
gr.exec();
}
I changed modality to NonModal,however the problem is without change. The Non-Modal mean:"The window is not modal and does not block input to other windows." <- from documentation
By documentation is recommended to avoid used .exec(). The alternatives are .show() and open(), which i tried. After the modification, the second window is shut down immediately after opening. after open immediately shut down.
Do you have any idea, how to solve that?
Graphics gr; defines a local variable, so the object is destructed as soon as it goes out of scope (at the end of your function).
In Qt, the typical approach is to work with pointers to Qt widgets (and, more generally, QObjects), but have a parent for each – the parent will clean it up.
Try this instead:
auto gr = new Graphics(this);
gr->setWindowModality(Qt::NonModal); // this is the default, no need for this call
gr->show();
This way the window will survive until your main window is destructed. In Qt there is also a mechanism for widgets/objects to self-destruct:
this->deleteLater();
So for example if you want to close and cleanup gr you can use that mechanism (you could also store gr as a member and call gr->deleteLater().

In Qt main function, how does QApplication learn about Mainwindow?

Looking at a simplest Qt Widget sample application that you can find from almost every Qt tutorial:
#include "notepad.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Notepad w;
w.show();
return a.exec();
}
There is one thing puzzles me. There are two major variables a and w here. a.exec() starts Qt's main loop, which suppose to interact with the main GUI component w. However, both of them live on stack and I don't see any code pass w somehow to a. So how does a be aware of the existence of w?
Does the constructor of w initializes a static data structure that a can access to check the top-level widgets?
Qt preprocess your code and build the real c++ code before compiling, its at this moment QApplication wrap all Q object in the main.cpp file and build the rest of the code from it.

Qt must construct QApplication before a QWidget

Qt recently started crashing without having a reason for it. The most recent one which is currently grinding my nerves down to a pulp is crashing due to starting another form programmatically. The "must construct QApplication before a QWidget" apparently is a common issue with Qt 5.7.* versions and the solutions I have found so far in StackOverflow haven't helped me.
This is a screenshot of the error message I got after the application crashed:
And here is the bit of the code that I remove which allows me to restart the application without any noticeable problems:
#include "operations.h"
Operations o;
void mainWindow::on_thisButton_clicked()
{
o.show();
this->hide();
}
----
The main.cpp as requested :)
#include "mainWindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
mainWindow w;
w.show();
return a.exec();
}
Try this:
#include "operations.h"
void mainWindow::on_thisButton_clicked()
{
Operations *o = new Operations();
o->show();
this->hide();
}
You might want to declare Operations *o as a member of mainWindow and initialize it the the constructor if you don't want to create a new one each time the button is clicked.
"must construct QApplication before a QWidget" is the standard type of error you get with Qt applications, when linking something incompatible ( like mixing debug/release ).
So in most use cases this indicates a build problem and has nothing to with the code itself.
Don't create Operations object as a global variable, as it will be created as a static BEFORE running main(), therefore the error message is simply correct and relevant. This is a C++ issue, not a Qt one.
All other suggestions work because you now create the object at the right time, after the QApplication...
Okay, I have managed to find a solution, however, it is borderline idiotic as it does not make any sense why it does not work in its prior state. Technically, all you need to do in order to have the error not appearing is to stick the declaration of the form class you are referring within the function itself(ie Operations o;).
Here is the code solution itself:
#include "operations.h"
void mainWindow::on_thisButton_clicked()
{
Operations o;
o.show();
this->hide();
}
Bare in mind that this is not the end of all problems as I currently have the problem of the new form closing in the very same 1 second period it opens. If I manage to solve it I will update my solution.

Qt5 QuickView cannot create window: no screens are available

I receive this error (title, below) whenever I try to run the following code:
#include <QCoreApplication>
#include <QQuickView>
int main(int argc, char *argv[]){
QCoreApplication app(argc, argv);
QQuickView view;
view.setSource(QUrl::fromLocalFile("app.qml"));
QObject *object = (QObject*)view.rootObject();
view.show();
delete object;
return app.exec();
}
Cannot create window: no screens available
The program has unexpectedly finished.
All I can find online for that error are bug reports arising from specific conditions significantly more involved than the above.
app.qml is a file that runs fine alone, i.e. without the above C++ and in a separate project configured as a 'Qt Quick UI'. Giving it's qrc:// path, or deliberately specifying a file which does not exist has no effect.
Note the QObject* cast - this was not present in the docs, but without it:
/main.cpp:11: error: cannot initialize a variable of type 'QObject *' with an rvalue of type 'QQuickItem *'
How should this be done?
The QCoreApplication can be used with console application, not with GUI ones, i.e. you have to use a QGuiApplication object. It seems to me that you created a console application instead of a graphical one.
You can create a proper application via the Qt Quick Application, add your "app.qml" as a resource to that project and call such a file instead of the default "main.qml", provided by the project template.
If you want to quick fix your current project, just check that the .pro file is set to import GUI libraries:
QT += gui qml quick
Set your qml file as a resource:
Create a new resource file via file -> new File or Project... -> Qt -> Qt Resource File
Right click the newly created .qrc file and click add existing file to add your "app.qml" file
Finally, rewrite your main like this:
#include <QQuickView>
#include <QGuiApplication>
int main(int argc, char *argv[])
{
QGuiApplication a(argc, argv); // GUI APPLICATION!!!
QQuickView view;
view.setSource(QUrl(QStringLiteral("qrc:///app.qml")));
view.show();
return a.exec();
}
However, going for the Qt Quick Application project would be the wiser choice.

Qt 5.1 QApplication Without Display - QXcbConnection: Could not connect to display

I'm using Qt5.1 and I'm trying to create a QApplication without a display. I need to draw text with QPainter, so I need to use QApplication (or QGuiApplication), otherwise I get a segfault.
The application worked fine in Qt4.8, but fails in Qt5.1 on a headless version of Ubuntu with the error:
"QXcbConnection: Could not connect to display".
In Qt 4.8, I was able to use the following constructor with GUIenabled = false to create a QApplication that did not require a display:
QApplication::QApplication ( int & argc, char ** argv, bool GUIenabled )
In Qt5.1, the constructor for QApplication no longer has the GUIenabled flag.
I scanned the source code briefly, and there does seem to be a flag in the QApplication constructor, but it is undocumented as to what options can be used in that flag. Using "false" does not work.
How can I create a QApplication without a display? Is there an alternative method to telling QApplication GUIenabled = false? Alternatively, can I create a QCoreApplication that will not segfault when drawing text with QPainter on a QImage?
Yes, that's a Qt 3 (?) thing that is gone in Qt 5. Try running your application with the -platform offscreen command line option instead.
Note that you don't need QApplication or linking to QtWidgets to just draw upon a QImage, using QGuiApplication (and linking to QtGui) is sufficient.
If you want to create an app without GUI, you need to use QCoreApplication instead of QApplication.
Just hit this same issue. Really annoying that it at least isn't a compile error. My solution was just to use pointers and heap objects like,
QCoreApplication* app = 0;
Display* display = XOpenDisplay(NULL);
if (display)
{
XCloseDisplay(display);
app = new QApplication(argc, argv);
qobject_cast<QApplication*>(app)->setQuitOnLastWindowClosed(false);
}
else
{
app = new QCoreApplication(argc, argv);
}
return app->exec();