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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Переключение между потоками (Решено)  (Прочитано 3797 раз)
lexaaleynik
Гость
« : Февраль 13, 2017, 12:07 »

Программе нужно обрабатывать хоткеи, когда сама программа не в фокусе (в трее). ОС - Линукс. Через QEvent это не работает. Через X11EventFilter, тоже не получилось. Зато получилось как описано здесь:
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();
}

Вопрос: как бы мне между итерациями в бесконечном цикле переключаться на другие потоки, не разрушая этот поток, и возвращаться обратно, чтобы отлавливать события хоткеев, и весь другой функционал приложения работал.
« Последнее редактирование: Февраль 13, 2017, 17:10 от lexaaleynik » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #1 : Февраль 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() асинхронно
Записан
lexaaleynik
Гость
« Ответ #2 : Февраль 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() асинхронно
Не понял вас, вы хотите сказать, что не нужно в отдельный поток выносить? А как же мне тогда и события от иксов получать в цикле и за его пределами другой код выполнять? Если не сложно - объясните поподробнее, как действовать?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #3 : Февраль 13, 2017, 14:09 »

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

Не понял вас, вы хотите сказать, что не нужно в отдельный поток выносить?
Выносить, ну в смысле если событий нет, то следящая нитка спит на XNextEvent и проснется только когда событие появится. Только добавить флажок (напр abort) чтобы она смогла завершиться при закрытии приложения

Так как усыпить поток, не разрушая его, и чтобы другой поток продолжил выполнение, а потом наоборот: другой поток усыпить, а этот - пробудить? А условие пробуждения куда? run() у меня правильно реализован? Не могли бы вы или какой-нибудь примерчик скинуть?
Записан
lexaaleynik
Гость
« Ответ #5 : Февраль 13, 2017, 16:40 »

Выносить, ну в смысле если событий нет, то следящая нитка спит на XNextEvent и проснется только когда событие появится. Только добавить флажок (напр abort) чтобы она смогла завершиться при закрытии приложения
Вообще вопрос общий, а как переключаться на другой поток без завершения текущего?
GUI-поток же как-то даёт другим потокам работать, сам при этом не завершаясь?
Записан
lexaaleynik
Гость
« Ответ #6 : Февраль 13, 2017, 17:09 »

Ох, лол!  Я поток запускал методом run(), вместо start(). Потому основной и повисал. Вопрос и закрыт.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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