Qприложение и обработка завершения работы X-сервера

#qt #x11

#qt #x11

Вопрос:

У меня есть приложение Qt, которое работает на компьютере с Linux, которое отображает окна пользовательского интерфейса на компьютере с Windows, на котором запущен X-сервер. Существует большая вероятность того, что пользователи моего приложения выйдут из Windows или отключат X-сервер, не завершив сначала работу моего приложения.

Есть ли способ справиться с неожиданным завершением работы X-сервера, чтобы приложение могло корректно завершить работу, сохранить сохраненные данные и т.д.? До сих пор я пытался привязать сигнал aboutToQuit от QApplication к слоту в моем приложении, плюс перехватывать все исключения в main. Ни то, ни другое не сработало так, как я ожидал.

Ответ №1:

Я думаю, что лучше всего попытаться справиться с этим с помощью обработки сигналов

в зависимости от того, как ОС завершает работу приложения, корректный выход может быть вообще невозможен.

Комментарии:

1. Я не уверен, что умирающий X-сервер выдаст какой-либо сигнал. Это странно, потому что цикл QApplication каким-то образом завершается (или приложение продолжало бы работать), просто, похоже, оно ничего не уведомляет о том, что оно завершается.

2. Такое поведение, соответствующее отправке вашему приложению чего-то вроде SIGTERM, прерывало бы выполнение вашей программы, не давая ей возможности что-либо с этим сделать. Я бы запустил обработчик сигналов и посмотрел, получает ли ваше приложение что-либо, на что оно может отреагировать.

Ответ №2:

Я не уверен, но, возможно, этот QCoreApplication::aboutToQuit() сигнал может вам помочь.

Комментарии:

1. Я упоминал в исходном сообщении, что я уже пробовал это. Насколько я могу судить, сигнал никогда не срабатывает.

Ответ №3:

Если соединение с X-сервером потеряно, то libX11 внутри приложения вызывается _XIOError() функция, которая вызывает _XDefaultError обработчик, который вызывает exit() . Это можно переопределить с помощью пользовательского обработчика:

 #include <X11/Xlib.h>

static int handler(Display *dpy)
{
    /* 
     * cleanup
     * ...
     */

    exit(1);
    return 0;
}

...

int main(int argc, char** argv)
{
    QApplication app(argc, argv);
    XSetIOErrorHandler(handler);
    ...
  

Лучше все равно вызывать exit() в обработчике, потому что Qt в любом случае отключится без надлежащего X-соединения.