Russian Qt Forum

Qt => Вопросы новичков => Тема начата: lexaaleynik от Февраль 13, 2017, 12:07



Название: Переключение между потоками (Решено)
Отправлено: lexaaleynik от Февраль 13, 2017, 12:07
Программе нужно обрабатывать хоткеи, когда сама программа не в фокусе (в трее). ОС - Линукс. Через QEvent это не работает. Через X11EventFilter, тоже не получилось. Зато получилось как описано здесь:
http://stackoverflow.com/revisions/22774310/4 (http://stackoverflow.com/revisions/22774310/4)

Чтобы прикрутить этот функционал к своему приложению мне надо сделать так, чтобы определённый код крутился в отдельном потоке в бесконечном цикле. Пошел по примитивному пути. Отнаследовался от QThread, переопределил run():
Код:
void run()
{
    Display* display = XOpenDisplay(0);
    Window root = DefaultRootWindow(display);
    Window current_focus_window;
    int revert;

    XSetErrorHandler(MyX11ErrorHandler);

    XGetInputFocus(display, &current_focus_window, &revert);
    XSelectInput(display,current_focus_window,KeyPressMask | KeyReleaseMask | FocusChangeMask);

    while(true)
    {
        XEvent event;
        XNextEvent(display, &event);
        switch (event.type)
        {
            case FocusOut:
                if(current_focus_window != root)
                    XSelectInput(display, current_focus_window, 0);
                XGetInputFocus(display, &current_focus_window, &revert);
                if(current_focus_window == PointerRoot)
                    current_focus_window = root;
                XSelectInput(display, current_focus_window, KeyPressMask|KeyReleaseMask|FocusChangeMask);
                break;

            case KeyRelease:
                qDebug() << event.xkey.keycode;
                break;
        }
    }
    exec();
}

Вопрос: как бы мне между итерациями в бесконечном цикле переключаться на другие потоки, не разрушая этот поток, и возвращаться обратно, чтобы отлавливать события хоткеев, и весь другой функционал приложения работал.


Название: Re: Переключение между потоками
Отправлено: Igors от Февраль 13, 2017, 13:25
Не работал с Линукс, смотрю доку
Цитировать
The XNextEvent() function copies the first event from the event queue into the specified XEvent structure and then removes it from the queue. If the event queue is empty, XNextEvent() flushes the output buffer and blocks until an event is received.
Выходит ничего переключать и не нужно, XNextEvent() асинхронно


Название: Re: Переключение между потоками
Отправлено: lexaaleynik от Февраль 13, 2017, 13:48
Не работал с Линукс, смотрю доку
Цитировать
The XNextEvent() function copies the first event from the event queue into the specified XEvent structure and then removes it from the queue. If the event queue is empty, XNextEvent() flushes the output buffer and blocks until an event is received.
Выходит ничего переключать и не нужно, XNextEvent() асинхронно
Не понял вас, вы хотите сказать, что не нужно в отдельный поток выносить? А как же мне тогда и события от иксов получать в цикле и за его пределами другой код выполнять? Если не сложно - объясните поподробнее, как действовать?


Название: Re: Переключение между потоками
Отправлено: Igors от Февраль 13, 2017, 14:09
Не понял вас, вы хотите сказать, что не нужно в отдельный поток выносить?
Выносить, ну в смысле если событий нет, то следящая нитка спит на XNextEvent и проснется только когда событие появится. Только добавить флажок (напр abort) чтобы она смогла завершиться при закрытии приложения


Название: Re: Переключение между потоками
Отправлено: lexaaleynik от Февраль 13, 2017, 14:35
Не понял вас, вы хотите сказать, что не нужно в отдельный поток выносить?
Выносить, ну в смысле если событий нет, то следящая нитка спит на XNextEvent и проснется только когда событие появится. Только добавить флажок (напр abort) чтобы она смогла завершиться при закрытии приложения

Так как усыпить поток, не разрушая его, и чтобы другой поток продолжил выполнение, а потом наоборот: другой поток усыпить, а этот - пробудить? А условие пробуждения куда? run() у меня правильно реализован? Не могли бы вы или какой-нибудь примерчик скинуть?


Название: Re: Переключение между потоками
Отправлено: lexaaleynik от Февраль 13, 2017, 16:40
Выносить, ну в смысле если событий нет, то следящая нитка спит на XNextEvent и проснется только когда событие появится. Только добавить флажок (напр abort) чтобы она смогла завершиться при закрытии приложения
Вообще вопрос общий, а как переключаться на другой поток без завершения текущего?
GUI-поток же как-то даёт другим потокам работать, сам при этом не завершаясь?


Название: Re: Переключение между потоками
Отправлено: lexaaleynik от Февраль 13, 2017, 17:09
Ох, лол!  Я поток запускал методом run(), вместо start(). Потому основной и повисал. Вопрос и закрыт.