App crashes when using QCoreApplication in library
-
And also, why are you faking the arguments to the
QCoreApplication
?
It depends on them to do some stuff with paths and such.
Pass them along frommain()
!And also (2):
Why do you create the application object in a library?@kshegunov I don't understand the second segment, what do you mean
application object
, if you mean GUI objects then no there is no GUI objects created in the library,
the library works without any help of the application -
@jamalabo said in App crashes when using QCoreApplication in library:
this->app = new QCoreApplication(n, nullptr);
From https://doc.qt.io/qt-6/qcoreapplication.html#QCoreApplication
Warning: The data referred to by argc and argv must stay valid for the entire lifetime of the QCoreApplication object. In addition, argc must be greater than zero and argv must contain at least one valid character string.
-
I have tried this:
inGUI
MY_LIB::DownloadManager::create_application(argc, argv); MY_LIB::DownloadableContent* content = MY_LIB::DownloadManager::create_content(url); connect(content, &MY_LIB::DownloadableContent::headersLoaded, this, &MainWindow::headersLoaded); content->loadHeaders();
in
LIB
QNetworkAccessManager MY_LIB::DownloadManager::get_network_manager() { return QNetworkAccessManager(get_application()); } void MY_LIB::DownloadableContent::loadHeaders() { QNetworkAccessManager manager = DownloadManager::get_network_manager(); connect(&manager, &QNetworkAccessManager::finished, this, &DownloadableContent::http_headers_loaded); manager.head(this->gen_request()); } void MY_LIB::DownloadableContent::http_headers_loaded(QNetworkReply *reply) { // process headers emit headersLoaded(); }
I'm new to c++ & qt so if there is any "bad practice" I'm happy to hear suggestions.
-
Hi,
Is your GUI application a Qt application as well ?
-
So it is likely:
- You have a static instance of your DownloadableContent
- You try to use it before creating your QApplication object
If the first one: stop doing that.
If the second, as mentioned clearly in the documentation, QxxxApplication must be instanciated first and before any other QObject.From the looks of it, your DownloadableManager class is either not properly implemented or used but in any case, it's not there that you should create the QApplication instance.
-
Look, all of this is going the same way, so I'll spill it:
Just structure your application, as one'd normally do (like shown in a Qt example) and the problem is going to go away on its own. You don't appear to really need to wrap around the application object -
QCoreApplication
instance, to answer your previous question - and you really don't appear to need anything exotic here. So, you'd be doing yourself a service to stick to the beaten path.int main(int argc, char ** argv) { QCoreApplication app(argc, argv); // ... // Stuff that the library provides/needs/executes // You can pass the application object to it here, or get it inside the library directly with qApp, if you need to. return QCoreApplication::exec(); }
-
@kshegunov I don't understand where should I put the
QCoreApplication
? if the GUI is running onQApplication
In GUI
int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.set_arguments(argc, argv); w.show(); return a.exec(); }
question: should I use the same
QxxxApplication
for theGUI
and theLIB
? and if so I get the errorQEventLoop: Cannot be used without QApplication
and If I try to pass the app/MainWindow as the parent it's throw the errorQObject: Cannot create children for a parent that is in a different thread
-
@kshegunov I don't understand where should I put the
QCoreApplication
? if the GUI is running onQApplication
In GUI
int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.set_arguments(argc, argv); w.show(); return a.exec(); }
question: should I use the same
QxxxApplication
for theGUI
and theLIB
? and if so I get the errorQEventLoop: Cannot be used without QApplication
and If I try to pass the app/MainWindow as the parent it's throw the errorQObject: Cannot create children for a parent that is in a different thread
No, there's only one
QApplication
object, the one inmain()
! Also I really see no reason for you getting the thread errors, are you using threads? -
No, there's only one
QApplication
object, the one inmain()
! Also I really see no reason for you getting the thread errors, are you using threads?@kshegunov no but I'm calling the code on a
slot
in MainWindow (on button click), (I don't know if this runs on different thread than MainWindow) -
@kshegunov no but I'm calling the code on a
slot
in MainWindow (on button click), (I don't know if this runs on different thread than MainWindow)@jamalabo said in App crashes when using QCoreApplication in library:
I don't know if this runs on different thread than MainWindow
It doesn't, then I imagine you have static
QObject
s that are initialized before they're allowed to, a.k.a. "theQApplication
object must always be the first one created and the last destroyed". So, as said, create your application object, then pass control to your library to do whatever it does, and when that's done continue on to start the event loop withexec()
.Your code looks more or less okay, assuming you've removed all
QApplication
creation from theMainWindow
and/or related classes. -
@kshegunov it seems like it's working but not properly
void MY_LIB::DownloadableContent::loadHeaders() { printf("load-headers\n"); QNetworkAccessManager manager; printf("manager\n"); connect(&manager, &QNetworkAccessManager::finished, this, &DownloadableContent::http_headers_loaded); manager.head(this->gen_request()); } void MY_LIB::DownloadableContent::http_headers_loaded(QNetworkReply *reply) { printf("headers-loaded"); emit headersLoaded(); }
after running this code I only get the output
load-headers manager
it seems like slots are not called and it's an event loop issue.
should I pass the QParent (app) param toQNetworkAcessManager
? -
@kshegunov I don't understand where should I put the
QCoreApplication
? if the GUI is running onQApplication
In GUI
int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.set_arguments(argc, argv); w.show(); return a.exec(); }
question: should I use the same
QxxxApplication
for theGUI
and theLIB
? and if so I get the errorQEventLoop: Cannot be used without QApplication
and If I try to pass the app/MainWindow as the parent it's throw the errorQObject: Cannot create children for a parent that is in a different thread
@jamalabo said in App crashes when using QCoreApplication in library:
I don't understand where should I put the
QCoreApplication
? if the GUI is running onQApplication
QApplication
inheritsQCoreApplication
.- You can only have one instance of
Q___Application
in your program.
So, you cannot create both a
QApplication
and aQCoreApplication
in the same program.question: should I use the same
QxxxApplication
for theGUI
and theLIB
?Yes. Definitely. They must share the same
QxxxApplication
instance. (And since your code uses widgets, then you must use QApplication) -
@kshegunov it seems like it's working but not properly
void MY_LIB::DownloadableContent::loadHeaders() { printf("load-headers\n"); QNetworkAccessManager manager; printf("manager\n"); connect(&manager, &QNetworkAccessManager::finished, this, &DownloadableContent::http_headers_loaded); manager.head(this->gen_request()); } void MY_LIB::DownloadableContent::http_headers_loaded(QNetworkReply *reply) { printf("headers-loaded"); emit headersLoaded(); }
after running this code I only get the output
load-headers manager
it seems like slots are not called and it's an event loop issue.
should I pass the QParent (app) param toQNetworkAcessManager
?@jamalabo said in App crashes when using QCoreApplication in library:
it seems like slots are not called and it's an event loop issue.
Well, that doesn't surprise me, your
QNetworkAccessManager
object dies as you leave the function. So either you make it a member to yourDownloadableContent
class, or create it on the heap (parented properly). And if you decide on the latter, please don't do it every time you pass through that method, just the first time.should I pass the QParent (app) param to QNetworkAcessManager?
Not necessarily, although usually you give parents to
QObject
instances. SinceDownloadableContent
already derives fromQObject
, what's wrong with giving theQNetworkAcessManager
object a parent of the object which "owns"/"contains" it (a.k.a.this
in this case)? -
@kshegunov
now it crashes.QNetworkAccessManager *NETWORK_COMBINER_LIB::DownloadableContent::get_manager() { return (!this->manager ? (this->manager = new QNetworkAccessManager()) : this->manager); } void NETWORK_COMBINER_LIB::DownloadableContent::loadHeaders(QObject *parent) { printf("load-headers\n"); QNetworkAccessManager *pManager = this->get_manager(); printf("pManager\n"); connect(pManager, &QNetworkAccessManager::finished, this, &DownloadableContent::http_headers_loaded); pManager->head(this->gen_request()); }
-
@kshegunov
now it crashes.QNetworkAccessManager *NETWORK_COMBINER_LIB::DownloadableContent::get_manager() { return (!this->manager ? (this->manager = new QNetworkAccessManager()) : this->manager); } void NETWORK_COMBINER_LIB::DownloadableContent::loadHeaders(QObject *parent) { printf("load-headers\n"); QNetworkAccessManager *pManager = this->get_manager(); printf("pManager\n"); connect(pManager, &QNetworkAccessManager::finished, this, &DownloadableContent::http_headers_loaded); pManager->head(this->gen_request()); }
@jamalabo said in App crashes when using QCoreApplication in library:
now it crashes.
Look at your debugger's stack trace to see why it crashed.
!this->manager ?
Did you initialize the pointer to
nullptr
? -
@jamalabo said in App crashes when using QCoreApplication in library:
yes it's initialized to
nullptr
OK, so it sounds like initializing
nullptr
stopped the crash.but still does nothing (the request is not sent)
Time to start debugging.
- What does your QNetworkRequest look like?
- Does the QNetworkAccessManager emit any other signals after you called
head()
? https://doc.qt.io/qt-5/qnetworkaccessmanager.html#signals - Does the QNetworkReply emit any signals after you called
head()
? (The QNetworkReply object is returned byQNetworkAccessManager::head()
) https://doc.qt.io/qt-5/qnetworkreply.html#signals