Завершение консольных приложений Qt (Linux, Windows)

Завершение консольной программы Qt в Qt CreatorКонсольная программа Qt не выходит после завершения всех действий. Это возникает из-за того, что в конце программы запускается очередь сообщений, которая работает в главном потоке. Она необходима для обработки сигналов и слотов. Очередь запускается строкой:

return a.exec();

Если не используются потоки, сигналы и слоты то можно заменить эту строку стандартной:

return 0;

Но так совсем не интересно. Поэтому было решено научиться корректно выходить из консольных приложений написанных с помощью Qt. Нормально выходить в моем понимании означает, что все потоки останавливаются, а память освобождается. CTRL+C! Не думая, данная комбинация клавиш была принята в качестве конечной цели для выхода из приложения. Порывшись в интернете, нашел несколько решений. После их тестирования оставил только одно.

Решение заключается в создании нового объекта, который содержит в своём конструкторе функцию signal. Функция определяет способ обработки сигналов с указанием номера сигнала (Specifies a way to handle those signals with the signal number specified by sig). Для примера назвал класс CleanExit. Вот его заголовочный файл:

#ifndef CLEANEXIT_H
#define CLEANEXIT_H

#include <QObject>

#include <QtCore/QCoreApplication>
#include <QDebug>
#include <csignal>

class CleanExit : public QObject
{
    Q_OBJECT

public:

    explicit CleanExit(QObject *parent = 0);

private:

    static void exitQt(int sig);
};

#endif // CLEANEXIT_H

Файл исходного кода:

#include "cleanexit.h"

static CleanExit *pCleanExit;

CleanExit::CleanExit(QObject *parent ) : QObject(parent)
{
    pCleanExit = this;
    signal(SIGINT, &CleanExit::exitQt);
    signal(SIGTERM, &(CleanExit::exitQt));
}

void CleanExit::exitQt(int sig)
{
    qDebug() << "Shutdown application CTRL+C.";
    QCoreApplication::exit(0);
}

Далее остается создать объект в основном потоке программы, для консольных приложений это функция main:

#include <QtCore/QCoreApplication>
#include <cleanexit.h>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    CleanExit cleanExit;
    qDebug() << "test";

    return a.exec();
}

Вот так выглядит завершение работы программы в терминале Ubuntu и QtCreator’е:

Завершение консольной программы Qt в терминале Ubuntu   Завершение консольной программы Qt в Qt Creator

Upd. Попробовал в винде. Результат в терминале такой же как в Ubuntu, а вот QtCreator’е совсем по другому. Не знаю с чем это связано, но так как в терминалах работают одинаково, то, думаю, можно считать решение кроссплатформенным.

  

При использовании дочерних потоков выход из них будет происходить корректно. То есть если определить слот finished, то он выполнится. При аварийном завершении программы такого не происходило. Теперь всё нормально!

Запись опубликована в рубрике программирование с метками , , , , . Добавьте в закладки постоянную ссылку.

3 комментария на «Завершение консольных приложений Qt (Linux, Windows)»

  1. test говорит:

    Первый этап обработки исключения в «0x75606d67» в «hparser_test1.exe»: 0x40010005: Control-C.
    это получается при отладке в win-7, mvsc 10

    • alexei говорит:

      Возможно у меня использовался mingw. На сколько я помню, он раньше включался в поставку с Qt.

  2. richardmlldk говорит:

    Hello!
    I live in Denmark — the city of Copenhagen. I liked your forum. Razrishite to attach to it and communicate!
    Good wind and success!
    Richard Malcolm.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*