Program crash after setting QApplication::style twice - c++

#include <QApplication>
int main() {
QApplication::setStyle("windows");
QApplication::setStyle("windows");
}
This program produces Segmentation fault (core dumped). My qmake version is 4.7.2. Is this a Qt bug or my version is too old?

You must create an instance of QApplication before you set it's style. From the documentation
Ownership of the style object is transferred to QApplication, so
QApplication will delete the style object on application exit or when
a new style is set and the old style is still the parent of the
application object.
I'm assuming it's crashing because there is no QApplication to take ownership of the style. In general, creating the QApplication is one of the first things you should do.
#include <QApplication>
int main() {
QApplication a(argc, argv);
QApplication::setStyle("windows");
QApplication::setStyle("windows");
}

Related

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.

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.

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.

Problems Receiving QSerialPort Signals

I'm trying to write a simple program to test out the serial port, but am having trouble getting QSerialPort to work. I never receive signals from the QSerialPort object. I get 3 runtime warnings/errors that I think probably have something to do with it.
The errors are:
QApplication::qAppName: Please instantiate the Qapplication object first
QSocketNotifier: Can only be used with threads started with QThread
QSocketNotifier: Can only be used with threads started with QThread
The code snippet below is the smallest sample I can give to recreate the errors, it doesn't show me connecting signals but I think these errors are why I don't see them. If I don't call the open function none of the errors occur.
#include <QtGui/QApplication>
#include <QSerialPort>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
PowerBoardGUI w;
w.show();
QSerialPort* serial = new QSerialPort();
serial->setPortName("/dev/ttyS1");
serial->setBaudRate(QSerialPort::Baud9600);
bool isOpen = serial->open(QIODevice::ReadWrite);
serial->close();
delete serial;
return a.exec();
}
The test system is Redhat 5.6. A static version of QT 4.7.4. And the latest version of QSerialPort (built from GIT today).

What is "QApplication app(argc, argv)" trying to do?

#include <QtGui/QApplication>
#include <QtDeclarative>
#include "qmlapplicationviewer.h"
int main(int argc, char **argv) {
QApplication app(argc, argv);
QmlApplicationViewer viewer;
viewer.setMainQmlFile("app/native/assets/main.qml");
viewer.showFullScreen();
return app.exec();
}
My C++ is a bit rusty. Can someone please explain to me what is "QApplication app(argc, argv)" trying to do ?
Is it trying to declare a function which takes in 2 arguments (argc and argv) and return a variable of type QApplication ?
The line
QApplication app(argc, argv);
creates a new instance of type QApplication and invokes the constructor of this class. In your example, the variable app now stores this instance. It is somewhat (semantically) a shorthand of this:
QApplication app = QApplication(argc, argv);
Here's a quote from Qt Docs:
The QApplication class manages the GUI application's control flow and
main settings.
QApplication contains the main event loop, where all events from the
window system and other sources are processed and dispatched. It also
handles the application's initialization, finalization, and provides
session management. In addition, QApplication handles most of the
system-wide and application-wide settings.
For any GUI application using Qt, there is precisely one QApplication
object, no matter whether the application has 0, 1, 2 or more windows
at any given time. For non-GUI Qt applications, use QCoreApplication
instead, as it does not depend on the QtGui library.
The QApplication object is accessible through the instance() function
that returns a pointer equivalent to the global qApp pointer.
So, the line
QApplication app(argc, argv);
creates an instance of the QApplication class.
QApplication is a Qt class that contains the main event loop.
When you write QApplication app(argc, argv);
you are creating a object app of this class, by calling its constructor with argc and argv
When int main(int argc, char **argv) is called while running the program, int argc is intialized to contain the number of arguments passed while running the program. char **argv contains an array of arguments passed to the program when executing it.
char* argv[0] will contain (point to) the name of the program, while the subsequent elements will point to the other arguments passed.
argc and argv are in turn, passed to the constructor of QApplication, so that one can pass Qt specific arguments when running your program.
For an example of such arguments try running ./yourProgramName --help in a terminal window
app() is not a function, it is a constructor call.
If you come from C# or Java or something, imagine it as
QApplication app = new QApplication( argc, argv );
Just that app would be a pointer this way, while it actually is the object itself if it is created like in your example.
In short, Qt needs a QApplication instance to run so signals&slots are processed (if you are using them) and events like painting etc are handled