Russian Qt Forum

Qt => Общие вопросы => Тема начата: puh от Январь 23, 2014, 13:41



Название: Qt_5.1.0 Не могу отловить сообщение о закрытии приложения
Отправлено: puh от Январь 23, 2014, 13:41
Здравствуйте.
Пробую отловить сообщение от системы о принудительном закрытии фонового приложения при выключении компьютера, чтобы кинуть сообщение в свой лог.
Посмотрел по форуму похожие темы, но ничего не получается.
Делаю следующее:
Код:
#include <QApplication>
#include <QTextCodec>
#include "mainwindow.h"

const static char * DEFAULT_PROG_CODEPAGE = "Windows-1251";


void setlog()
{
    bool openfile;
    QFile file("Log.txt");
    openfile = file.open(QFile::Append | QFile::Text);
    if (!openfile)
    {
        QMessageBox::critical(0, qAppName(), "Cannot open/create file");
    }
    else
    {
        QTextStream out(&file);
        // Для начала просто написать что-нибудь в ЛОГ-файл
        out << "open__\n";
        file.close();
    }
}

class MyApplication : public QApplication
{
public:
 MyApplication( int argc, char ** argv ) :
 QApplication( argc, argv )
 {
 }

 void commitData(QSessionManager &sm)
 {
     setlog();
 }

};


int main(int argc, char *argv[])
{
    QTextCodec::setCodecForLocale(QTextCodec::codecForName(DEFAULT_PROG_CODEPAGE));

    setlog();
//    QApplication a(argc, argv);
    MyApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}
Это очень сырой код, но для меня сейчас важно вообще перехватить сообщение и что-то сделать.

Может в пред.версия Qt это работало (?), но у меня ничего не выходит.


Название: Re: Qt_5.1.0 Не могу отловить сообщение о закрытии приложения
Отправлено: kambala от Январь 23, 2014, 13:50
в 4.х работало, в 5.х другой подход: см. void QGuiApplication::commitDataRequest(QSessionManager & manager) [signal]


Название: Re: Qt_5.1.0 Не могу отловить сообщение о закрытии приложения
Отправлено: puh от Январь 23, 2014, 16:58
Т.е. повесив на этот сигнал обработчик, я смогу что-то сделать до закрытия приложения?


Название: Re: Qt_5.1.0 Не могу отловить сообщение о закрытии приложения
Отправлено: kambala от Январь 23, 2014, 18:52
да


Название: Re: Qt_5.1.0 Не могу отловить сообщение о закрытии приложения
Отправлено: puh от Январь 24, 2014, 06:07
Делаю так:

main.c:
Код:
#include <QApplication>
#include <QTextCodec>
#include "mainwindow.h"

const static char * DEFAULT_PROG_CODEPAGE = "Windows-1251";

int main(int argc, char *argv[])
{
    QTextCodec::setCodecForLocale(QTextCodec::codecForName(DEFAULT_PROG_CODEPAGE));

    QApplication a(argc, argv);

    MainWindow w;

    w.show();

    QObject::connect(&a, SIGNAL(commitDataRequest(QSessionManager &)), &w, SLOT(slot_qapp(QSessionManager &)), Qt::DirectConnection);

    return a.exec();
}

MainWindow.h:
Код:
public slots:
        void slot_qapp(QSessionManager &sm);
MainWindow.cpp:
Код:
void MainWindow::slot_qapp(QSessionManager &sm)
{
    addLog("Log.txt", "Program stoped : " + QDateTime::currentDateTime().toString("yyyy.MM.dd::hh.mm"));
}
В конструкторе MainWindow вызывается ф-ция addLog("Log.txt", "Program started : " + QDateTime::currentDateTime().toString("yyyy.MM.dd::hh.mm")); - она проходит, т.е. грешить на эту ф-цию я не могу.

В итоге: программа висит в трее и при выключении компа запись в лог-файл не проходит.

Что не так?


Название: Re: Qt_5.1.0 Не могу отловить сообщение о закрытии пl
Отправлено: mezmay от Январь 24, 2014, 13:47
Вот рабочее решение отлова события выхода из системы:
Код:
// на примере события Windows 
bool cwin::nativeEvent( const QByteArray &eventType, void *message, long *result )
{
    Q_UNUSED(eventType)
    MSG* msg = static_cast<MSG*>(message);

    if(msg->message == WM_QUERYENDSESSION)
    {
        // здесь сделать всё что надо:
        m_connectThread.stop();
    }
    return QWidget::nativeEvent(eventType, message, result);
}
Это решение у меня тоже используется для фонового приложения, имеющего только иконку в трее.
Но, так как мы хотим ловить виндоусовские сообщения, надо вначале "показать" окно. В main я сделал так:
Код:
cwin w;
w.showMinimized();
w.hide();
В результате ничего не заметно, просто появляется иконка в трее, но сообщения идут в обработчик

еще одно красивое решение придумали здесь:
http://www.forum.crossplatform.ru/index.php?showtopic=9735&st=0&p=65870&#entry65870


Название: Re: Qt_5.1.0 Не могу отловить сообщение о закрытии приложения
Отправлено: sach от Январь 28, 2014, 19:50
Смотри QAbstractNativeEventFilter

Мой вариант для Windows
class WindowsNativeEventFilter : public QAbstractNativeEventFilter
{
public:
   WindowsNativeEventFilter();
   virtual bool nativeEventFilter(const QByteArray &, void *message, long *) Q_DECL_OVERRIDE ;
};

bool WindowsNativeEventFilter::nativeEventFilter(const QByteArray &, void *message, long *)
{
   MSG* msg = reinterpret_cast<MSG*>(message);
   if ( msg->message == WM_QUERYENDSESSION )
   {
      qApp->quit();
      return true ;
   }
   return false ;
}