Qt console application leaves terminal open on termination
-
I have a console application if there is any reason why it cannot start normally it exits, the application stops any running threads, then calls exit with an exit code.
This works and when running in Qt Creator debug I can see that:
12:56:35: Debugging has finished
However, the terminal window that was launched when the application started is left open. Is there a better cleaner way of terminating the application that will clean up and close down the terminal?
-
@SPlatten said in Qt console application leaves terminal open on termination:
Is there any way to avoid/prevent this?
Yes, doing multithreading in a proper way. As I wrote before: you are doing something wrongly somewhere in your code. And the warning even tells you what: you are using an objects as parent for another object which lives in another thread.
You should read this: https://doc.qt.io/qt-5/qobject.html#thread-affinity -
That's a good thing, right? You want the console window left open to see any output that was generated by the program. If it immediately closes then you lose the output that you might need.
When you get to the point where you want the app to automatically close the window then you need to spawn the program directly on the cmd(windoze) or xterm(X11) command line.
-
@SPlatten said in Qt console application leaves terminal open on termination:
the application stops any running threads
Are you sure you stopped all threads?
Did you check whether the process is still running? -
@jsulm doesn't return of a QT console app to the shellautomatically infer that all threads have stopped?
-
@Kent-Dorfman In my design I could have lots of child processes and therefore lots of child windows.
-
then it's not a console app. A console app is one that runs in a single shell window. if it spawning windows then it's a GUI app, right?
-
@SPlatten said in Qt console application leaves terminal open on termination:
In my design I could have lots of child processes and therefore lots of child windows
Does the terminal close when you close all child processes?
-
The main application is not a console application, the child processes it launches are console applications. If I launch the main application, it launches any child processes that are required. If I then close the main application windows, the application closes completely but the child processes are left running which isn't correct so I will look into this.
-
@jsulm , the main application is an engine which has a GUI front-end and launches configurable processes which serve as worker expansion modules. These add additional functionality to the main application, it's completely configurable so any number of modules can be added to the main application.
My head is a bit all over the place at the moment, because as well as creating and developing this application I am also working on my normal day job which is also Qt software development.
-
@jsulm The terminal is opened automatically when the child process is launched, this is the code that launches the process:
bool clsMainWnd::blnLaunch(QString strApp, QStringList& slstArgs, qint64& int64PID) { Q_ASSERT_X(clsMainWnd::mspobjProcess!=nullptr, "blnLaunch", "mspobjProcess is null!"); QString strFullPath(clsDebugService::strGetUserFolder(strApp)); int64PID = 0; qdbg() << "Checking for PID for: " << strFullPath; if ( blnGetPID(strFullPath, int64PID) == true ) { //Process already running, no action required } else { int intLastSep = strFullPath.lastIndexOf(QDir::separator()); qdbg() << "Process is NOT running, launching"; if ( intLastSep > 0 ) { QString strName = strFullPath.mid(intLastSep + 1) ,strPath = strFullPath.mid(0, intLastSep + 1); clsMainWnd::mspobjProcess->setArguments(slstArgs); clsMainWnd::mspobjProcess->setWorkingDirectory(strPath); clsMainWnd::mspobjProcess->setProgram(strName); if ( clsMainWnd::mspobjProcess->startDetached(&int64PID) == false ) { clsMainWnd::mspobjProcess->start(strFullPath, slstArgs); int64PID = clsMainWnd::mspobjProcess->processId(); if ( int64PID <= 0 ) { return false; } } } } if ( int64PID > 0 ) { qdbg() << "Process: " << strFullPath << " started, PID: " << QString::number(int64PID); return true; } return false; }
I think in posting this I've just spotted the problem, originally I was using startDetached then changed to start, but I see there is still a startDetached in the function. I need to look at this because it was a while back.
[Edit] The new launch function which I will now test:
bool clsMainWnd::blnLaunch(QString strApp, QStringList& slstArgs, qint64& int64PID) { Q_ASSERT_X(clsMainWnd::mspobjProcess!=nullptr, "blnLaunch", "mspobjProcess is null!"); QString strFullPath(clsDebugService::strGetUserFolder(strApp)); int64PID = 0; qdbg() << "Checking for PID for: " << strFullPath; if ( blnGetPID(strFullPath, int64PID) == true ) { //Process already running, no action required } else { int intLastSep = strFullPath.lastIndexOf(QDir::separator()); qdbg() << "Process is NOT running, launching"; if ( intLastSep > 0 ) { QString strName = strFullPath.mid(intLastSep + 1) ,strPath = strFullPath.mid(0, intLastSep + 1); clsMainWnd::mspobjProcess->setArguments(slstArgs); clsMainWnd::mspobjProcess->setWorkingDirectory(strPath); clsMainWnd::mspobjProcess->setProgram(strName); clsMainWnd::mspobjProcess->start(); int64PID = clsMainWnd::mspobjProcess->processId(); if ( int64PID == 0 ) { return false; } } } if ( int64PID > 0 ) { qdbg() << "Process: " << strFullPath << " started, PID: " << QString::number(int64PID); return true; } return false; }
-
@jsulm ,@Kent-Dorfman , now that I've fixed the launch function it works perfectly and when the main application is closed all the child processes automatically close, I am getting the following messages in the Application Output which are odd because despite the messages the child process is launched and running:
W00000000000000000014:QObject: Cannot create children for a parent that is in a different thread. W00000000000000000015:(Parent is QProcess(0x101f31360), parent's thread is QThread(0x101f05f40), current thread is clsThread(0x120d05ff0) W00000000000000000016:QObject: Cannot create children for a parent that is in a different thread. W00000000000000000017:(Parent is QProcess(0x101f31360), parent's thread is QThread(0x101f05f40), current thread is clsThread(0x120d05ff0) W00000000000000000018:QObject: Cannot create children for a parent that is in a different thread. W00000000000000000019:(Parent is QProcess(0x101f31360), parent's thread is QThread(0x101f05f40), current thread is clsThread(0x120d05ff0) W00000000000000000020:QObject: Cannot create children for a parent that is in a different thread. W00000000000000000021:(Parent is QProcess(0x101f31360), parent's thread is QThread(0x101f05f40), current thread is clsThread(0x120d05ff0) W00000000000000000022:QObject::connect: Cannot queue arguments of type 'QProcess::ProcessState' W00000000000000000023:(Make sure 'QProcess::ProcessState' is registered using qRegisterMetaType().) W00000000000000000024:QObject: Cannot create children for a parent that is in a different thread. W00000000000000000025:(Parent is QProcess(0x101f31360), parent's thread is QThread(0x101f05f40), current thread is clsThread(0x120d05ff0) D00000000000000000026:L00000053Fsimon.js[static bool clsMainWnd::blnLaunch]:
-
@SPlatten said in Qt console application leaves terminal open on termination:
Cannot create children for a parent that is in a different thread.
Check your thread usage (do not use an object created in another thread as parent). The warning tells you what is wrong. Also, why do you use threads? QProcess is already asynchronous...
-
-
@SPlatten said in Qt console application leaves terminal open on termination:
the threads are used to maintain asynchronous communication between the main application and the modules.
As a said: QProcess is already asynchronous. Why do you think you need threads.
And you you think you really need thread then check your implementation: you are doing something wrong with thread affinity. -