Russian Qt Forum

Qt => Общие вопросы => Тема начата: LisandreL от Декабрь 20, 2011, 11:10



Название: Выключение программы при отключении компьютера
Отправлено: LisandreL от Декабрь 20, 2011, 11:10
Есть приложение, которое висит в трее даже если ни одно из окон не открыто ( app.setQuitOnLastWindowClosed( false ); ).
Вопрос в том, как его правильно закрывать при отключении компьютера.

То есть я могу перегрузить у QApplication winEventFilter и поймать WM_QUERYENDSESSION или WM_ENDSESSION.
Наверняка и в других осях есть подобные события, но нет ли более кроссплатформенного решения?


Название: Re: Выключение программы при отключении компьютера
Отправлено: Пантер от Декабрь 20, 2011, 11:16
void QCoreApplication::aboutToQuit ()


Название: Re: Выключение программы при отключении компьютера
Отправлено: LisandreL от Декабрь 20, 2011, 11:29
Этот сигнал посылается, когда приложение собирается завершить цикл обработки событий, но дело-то как раз в том, что завершать его приложение и не думает, просто висит себе в трее, пока система не предложит просто жёстко прибить процесс.


Название: Re: Выключение программы при отключении компьютера
Отправлено: Пантер от Декабрь 20, 2011, 11:31
This may happen either after a call to quit() from inside the application or when the users shuts down the entire desktop session.


Название: Re: Выключение программы при отключении компьютера
Отправлено: LisandreL от Декабрь 20, 2011, 11:59
This may happen either after a call to quit() from inside the application or when the users shuts down the entire desktop session.

Ну по крайней мере в винде с отключенным quitOnLastWindowClosed этого не происходит (подозреваю что и в других осях так же и описанный aboutToQuit испускается при завершении desktop session только потому, что закрываются все окна).


Название: Re: Выключение программы при отключении компьютера
Отправлено: NicK от Декабрь 20, 2011, 12:17
Только сегодня задался таким же вопросом.
Можно пробовать ловить системное сообщение о завершении работы ОС:
Вариант для Windows:

Код
C++ (Qt)
#include <QApplication>
#include <QMessageBox>
#include <QDebug>
 
#include <qt_windows.h>
 
class MyApplication : public QApplication
{
public:
MyApplication( int argc, char ** argv ) :
QApplication( argc, argv )
{
}
bool winEventFilter(MSG * msg, long * retVal)
{
 
if (msg->message == WM_QUERYENDSESSION )
{
QMessageBox::information( NULL, "Session end", "Session end", "OK" );
*retVal = false;
return true;
}
return false;
}
 
};
 
 

Для Linux, к сожалению, не знаю. Надеюсь, кто-нибудь подскажет.


Название: Re: Выключение программы при отключении компьютера
Отправлено: andrew.k от Декабрь 20, 2011, 12:36
Под линукс нужно установить обработчик сигнала SIGTERM с помощью системного вызова signal (http://www.opennet.ru/man.shtml?topic=signal&category=2&russian=2)


Название: Re: Выключение программы при отключении компьютера
Отправлено: iroln от Декабрь 20, 2011, 12:52
У меня есть программка, которая висит в трее и при выключении компьютера что-то пишет куда-то в лог. Давно писал, уже не помню детали.

Вот такая функция есть:
Код
C++ (Qt)
void Application::commitData(QSessionManager &sm)
{
   timewatcher->slotWriteDataTimeToFile(); // при завершении сеанса ОС пишем данные в файл отчёта
 
// DEBUG: проверка работы менеджера сессий
// FIXME: когда все окна приложения не видны, эта функция почему-то не
// вызывается при завершении работы системы.
//
//    if(sm.allowsInteraction()) {
//        int r = QMessageBox::warning(timewatcher, tr("TimeWatcher"),
//                                     tr("Bla-Bla-Bla.\n"
//                                        "Do you really want to quit?"),
//                                     QMessageBox::Yes | QMessageBox::No);
//        if (r == QMessageBox::Yes) {
//            sm.release();
//        }
//        else {
//            sm.cancel();
//        }
//    }
}

Это то, или у вас другая проблема?

UPD:
Ага, и флаг тоже стоит
Код
C++ (Qt)
Application::setQuitOnLastWindowClosed(false);



Название: Re: Выключение программы при отключении компьютера
Отправлено: LisandreL от Декабрь 20, 2011, 13:49
NicK, почти так у меня и сделно:
Код:
#ifdef Q_WS_WIN

#include <qt_windows.h>

bool ServerApplication :: winEventFilter( MSG *message, long *result )
{
    UINT& msg = message->message;
    if ( msg == WM_QUERYENDSESSION || msg == WM_ENDSESSION )
    {
        *result = 1;
        quit();
        return true;
    }
    return QApplication::winEventFilter( message, result );
}
#endif


Под линукс нужно установить обработчик сигнала SIGTERM с помощью системного вызова signal (http://www.opennet.ru/man.shtml?topic=signal&category=2&russian=2)
Буду иметь в виду, хотя думаю через QApplication::*EventFilter для других осей примерно так же можно реализовать, просто хотелось некоторой универсальности.