Qt must construct QApplication before a QWidget - c++

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.

Related

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

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.

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().

Unable to find the error in this basic Qt snippet, but I am told that it exists for sure?

I've been recently trying to get into Qt to better understand class hierarchy and OOP. I just fell upon this question in a test bank, asking to "fix" this code to prevent compiler and runtime errors. However, I unfortunately couldn't find the solution and I wasn't able to come up with a solution myself. For me, all QObject-derived classes handle all memory deallocation. So the following code does not pose any problems that I can see, and it compiles.
#include <QLabel>
#include <QWidget>
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QLabel label("my string");
QWidget window;
label.setParent(&window);
window.show();
return a.exec();
}
For me, all QObject-derived classes handle all memory deallocation.
Exactly, that's why this sample code contains an error of the kind you'll see when you close window. Qt's parent-children system works in the way that the widget manages it's children's lifetime and deletes them when being deleted itself.
So, when QApplication quits ~QWidget() destructor is called, causing deletion of the label. Thus, ~QLabel() is called.
But on the other hand, when main is finished, local variables are being deleted, label is one of them. It is not a pointer but a value variable, we get another call of ~QLabel().
Double call of the destructor is the error. It can be fixed by creating label on a heap via new.
Qt handles memory management by parent-child relationships. If a parent widget/window is destroyed, it destroys all the children as well. In this instance the label is set as a child of the window, which means that the windows destructor will try to delete it. As it is create on the stack, the memory deallocation will fail. And even if it will not (assuming the memory manger silently ignores such call, which it should not), the label will be destroyed the second time when the execution of main() finishes, leading to double-delete. As others have already pointed out, you could solve it by allocating the label on the heap using QLabel *label = new QLabel("my string"); instead, but there is an even simpler solution: re-order the creation of the window and the label:
#include <QLabel>
#include <QWidget>
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QWidget window;
QLabel label("my string");
label.setParent(&window);
window.show();
return a.exec();
}
This way the label will be destroyed before the window. That will remove the label from the windows children list and allow correct termination.
Finally, the use of the setParent() method is actually relatively rare in Qt. Normally you would have passed the parent to the constructor of the child widget:
QWidget window;
QLabel label("my string", &window); // No need for setParent()
This requires that the window already exists, and is Qt-s way of leading you towards the correct solution.

QtWebKit c++ connect: cannot convert QWebView to SOCKET

Recently started doing some programming for Windows and I simply can't get my program to work. I am trying to achieve an environment in which I mainly can use HTML for the frontend and control the backend with Javascript. On Linux I've managed to add functions and stuff to the "JavaScriptCore" but Windows haven't been to kind with me.
Currently I'm trying to catch the URL change event, allowing for special URLs to execute commands, however I get the following error:
error: C2664: 'connect' : cannot convert parameter 1 from 'QWebView *' to 'SOCKET'
There is no context in which this conversion is possible
I didn't manage to find a single search result concerning "QWebView to SOCKET" so I have no clue what to do but to ask you guys.
Here is my code. I'm not too good with programming to please be gentle ;)
#include <QtGui>
#include <QtWebKit>
#include <QApplication>
#include <QWebView>
#include <iostream>
using namespace std;
void test()
{
cout << "Hello world";
}
int main(int argc, char** argv) {
QApplication app(argc, argv);
QWebView view;
view.setWindowFlags(Qt::CustomizeWindowHint);
view.setWindowFlags(Qt::FramelessWindowHint);
view.setFixedSize(1000,600);
view.setStyleSheet("background:transparent;");
view.setAttribute(Qt::WA_TranslucentBackground);
view.setUrl(QUrl("http://google.com"));
view.setWindowTitle("test v0.1");
connect(view, SIGNAL(urlChanged(QUrl)), SLOT(test()));
view.show();
return app.exec();
}
Try this instead:
QObject::connect(&view, &QWebView::urlChanged, test);
You are using the old connection syntax which works only with QObjects and slots, test is not a slot and it is not a function of a QObject derived class, it is a free funciton, so you have to use the new syntax, available since Qt 5.
When you are not inside a QObject you don't have access to connect(), that is why my example uses the QObject namespace to invoke it in main(). In your case as DNT noted it is just some other function that happens to be named "connect".
Another mistake you made is you passed the view, but connect() works with pointers, so you have to use the & operator to get a pointer to the view.

Can't update Text Edit Text QT

I'm having an issue. My textEditBox doesn't seem to be updating when my Addtext function is called.
Here's my Addtext:
void CTextBox::AddText(QString string, QString spriteString)
{
textBrowser->setText(string + spriteString);
update();
}
Another class then calls the function and it should add text to the textbox but it doesn't.
How do you call CTextBox::AddText()? update() only schedules a paintEvent() for later, when the program returns to the event loop. That means that
you actually need to have an event loop, ie. at some point you need to call qApp->exec();
you need to allow the programm some time to qApp->processEvents() (insert that after update()), if you want any paining done within a blocking while() {...} or something like that.
Edit: Come to think of it, you shouldn't even need to call update() nor processEvents() if your program returns to the event loop some time after AddText, so there really seems to be an issue with the event loop. Post your main.cpp, will you?
Here is a trivial example of what it sounds like you are trying to do. Maybe you can see where your design differs?
Notice: no explicit update() is needed. I think that's a red herring. I think it far more likely that (1) you are somehow calling your AddText method with empty strings, or (2) your real text edit is a different variable, and have somehow created two of them and are updating one that just exists in memory and was never added to a layout. Perhaps the code of your FileLoaderQT would help? (You can edit your question rather than posting in comments.)
#include <QtGui>
int main(int argc, char **argv) {
QApplication app(argc, argv);
QMainWindow w;
QTextEdit *edit = new QTextEdit;
w.setCentralWidget(edit);
edit->setText("Hello world!");
w.show();
edit->append("Hello world again!");
return app.exec();
}