Russian Qt Forum
Ноябрь 25, 2024, 00:46 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Qt_5.1.0 Не могу отловить сообщение о закрытии приложения  (Прочитано 4942 раз)
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 это работало (?), но у меня ничего не выходит.
Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« Ответ #1 : Январь 23, 2014, 13:50 »

в 4.х работало, в 5.х другой подход: см. void QGuiApplication::commitDataRequest(QSessionManager & manager) [signal]
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
puh
Гость
« Ответ #2 : Январь 23, 2014, 16:58 »

Т.е. повесив на этот сигнал обработчик, я смогу что-то сделать до закрытия приложения?
Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« Ответ #3 : Январь 23, 2014, 18:52 »

да
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
puh
Гость
« Ответ #4 : Январь 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")); - она проходит, т.е. грешить на эту ф-цию я не могу.

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

Что не так?
Записан
mezmay
Гость
« Ответ #5 : Январь 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
« Последнее редактирование: Январь 24, 2014, 13:58 от mezmay » Записан
sach
Гость
« Ответ #6 : Январь 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 ;
}
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.127 секунд. Запросов: 23.