2

I'm making an application for Mac OS X in Qt, and wanted to spawn a thread that doesn't close on application close.

Is this possible? If so, how? I don't want the process to be stopped if a user force quits the application.

Thanks in advance.

Note: If this is not possible, is there any way I can make this happen? (Maybe with calling a command in bash?)

Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313
Flare Cat
  • 591
  • 2
  • 12
  • 24
  • 3
    As a user, I would not be too happy about this. When I close some application, I want it to be closed. – Baum mit Augen Sep 07 '16 at 20:15
  • @BaummitAugen I am aware of that. The issue is that if it is in the middle of a cleanup process after a cancellation, and the user quits it, then the cleanup process would not have finished. – Flare Cat Sep 07 '16 at 20:21
  • 3
    A thread cannot exist without an application. In your case the application should wait for the cleanup thread to finish working (using `join`). – Violet Giraffe Sep 07 '16 at 20:26
  • 2
    So catch the termination signal instead. If the user force-kills your app with some uncatchable signal, any data loss is their own fault. – Baum mit Augen Sep 07 '16 at 20:27
  • This smells of an [XY Problem](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). Please edit the question to remove irrelevant implementation details that presume a particular solution. You don't care about any threads. All you want is for some code to run after the user has Quit (⌘-Q) the application, and for the dock icon/menubar to disappear as expected. Thus: ask for what you really want. – Kuba hasn't forgotten Monica Sep 08 '16 at 13:11

4 Answers4

3

it's possible to achieve your goal by initiating a new process via QProcess::startDetached, as per documents http://doc.qt.io/qt-4.8/qprocess.html#startDetached

Starts the program program with the arguments arguments in a new process, and detaches from it. Returns true on success; otherwise returns false. If the calling process exits, the detached process will continue to live.

Unix: The started process will run in its own session and act like a daemon.

Edit:

Here is an example for MacOS

// run start script
QString scriptPath = "path-to-start-script/start.sh" ;
QString cmd = "open -a " + scriptPath;
QProcess::startDetached(cmd);
Community
  • 1
  • 1
HazemGomaa
  • 1,620
  • 2
  • 14
  • 21
  • Thank you. In the documentation, one argument for calling `QProcess::startDetached` is `const QString & program`. What exactly would that string contain? – Flare Cat Sep 07 '16 at 20:38
  • 1
    check this out http://stackoverflow.com/questions/4185388/qt-qprocess-is-not-working – HazemGomaa Sep 07 '16 at 20:42
  • 1
    Ahh, thank you. Will try this out when I get a chance, and will report how it worked in my app. – Flare Cat Sep 07 '16 at 20:43
  • 1
    The 1st argument is the path to your app, and 2nd (optional) is the list of the arguments .. – HazemGomaa Sep 07 '16 at 20:43
  • you welcome, also find more examples here http://www.qtcentre.org/threads/61261-Qt-start-new-application-and-quit – HazemGomaa Sep 07 '16 at 20:45
2

When you terminate a process, all threads within that process die - the process is the thread "container". If you want to spawn something that lives on beyond your current process, then spawn a new independant process.

Jesper Juhl
  • 30,449
  • 3
  • 47
  • 70
1

If your user force-quits the application, that usually means that they want to control the energy or resource expenditure on their system. Thinking that you know better than the user would be rather in the user's face. Don't anger your users :)

All you really want is:

  1. For the process to survive quitting it through normal means (pressing ⌘-Q, selecting Quit from the menu, closing the last window, etc.).
  2. For the dock icon to disappear after the GUI has been quit, as is the normal and expected behavior.
  3. For a cleanup code to run after the GUI has vanished.

To that effect, you only need to hide the dock icon/menubar and then perform the cleanup:

main.mm

// https://github.com/KubaO/stackoverflown/tree/master/questions/hidedock-39378276
#include <QtWidgets>
#include <AppKit/AppKit.h>

void hideDockIcon() {
    [NSApp setActivationPolicy: NSApplicationActivationPolicyProhibited];
}

int main(int argc, char ** argv) {
    QApplication app{argc, argv};
    QLabel label{"Quit Me"};
    label.setMinimumSize(200, 100);
    label.show();
    int rc = app.exec();
    hideDockIcon();
    qDebug() << "cleaning up";
    QThread::sleep(5);
    qDebug() << "cleanup finished";
    return rc;
}

hidedock-39378276.pro

QT = widgets
CONFIG += c++11
TARGET = hidedock-39378276
TEMPLATE = app
OBJECTIVE_SOURCES += main.mm
LIBS += -framework AppKit
Community
  • 1
  • 1
Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313
-1

If u mean closing of Gui window by "Application Close" then it can be done easily...

#include "MainWindow.h"
#include <QApplication>

//////////////////////////////////////
#include <thread>
struct blabla {
    std::thread th;
    blabla():th([]{
        // body of your thread  
    }) {}
    ~blabla(){
        if(th.joinable())
            th.join();
    }   
} singleton_obj;
/////////////////////////////////////

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec();
}

Now the applicaton window will quit but the daemon thread will run n background... Enjoy

pPanda_beta
  • 618
  • 7
  • 10
  • How's your code is related to the question, or to your answer ? You are not using Qt and your main{} is empty ! ... – HazemGomaa Sep 08 '16 at 13:23
  • No no no U r free to write anything in main This piece of code should be placed in "main.cpp" just right after #include Or you can place that singleton_obj any where but either in global scope or in static storage class... – pPanda_beta Sep 08 '16 at 18:56