Qt Application: Имитация модального поведения (включить / отключить пользовательский ввод) - PullRequest
2 голосов
/ 06 января 2010

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

Не так важно, чтобы диалог оставался поверх приложения, хотя, если вы можете подсказать, как это сделать, не прибегая к поведению Always-On-Top, это также было бы неплохо.

Отметим, что приложение компилируется как под Windows, так и под Linux. Кроме того, это не вариант для непосредственного запуска диалогов. Они находятся в отдельных исполняемых файлах. Кроме того, приложение представляет собой довольно сложную часть программного обеспечения, поэтому отключение виджетов по отдельности не вариант или, по крайней мере, не очень жизнеспособный.

Я нашел функции lock () и unlock () в классе QApplication в Qt 3.3. В настоящее время мы используем Qt 4.5, который, похоже, не имеет этого API. На самом деле класс QApplication Qt 4.5, по-видимому, также не предоставляет доступ к циклу событий.

Подводя итог: Как отключить / включить пользовательский ввод в приложении Qt, сочетания клавиш мыши и клавиатуры?

Ответы [ 3 ]

5 голосов
/ 07 января 2010

gj уже предложил это решение, но я подумал, что вставлю свою реализацию просто для справки:

Реализация класса фильтра, который будет поглощать действия пользователя.

class BusyAppFilter : public QObject
{
protected:
    bool eventFilter( QObject *obj, QEvent *event );
};


bool BusyAppFilter::eventFilter(QObject *obj, QEvent *event)
{
    switch ( event->type() )
    {
    case QEvent::KeyPress:
    case QEvent::KeyRelease:
    case QEvent::MouseButtonPress:
    case QEvent::MouseButtonDblClick:
    case QEvent::MouseMove:
    case QEvent::HoverEnter:
    case QEvent::HoverLeave:
    case QEvent::HoverMove:
    case QEvent::DragEnter:
    case QEvent::DragLeave:
    case QEvent::DragMove:
    case QEvent::Drop:
        return true;
    default:
        return QObject::eventFilter( obj, event );
    }
}

Затем поместите этот код в свой класс QApplication:

QCursor busyCursor( Qt::WaitCursor );
setOverrideCursor( busyCursor );

BusyAppFilter filter;
installEventFilter( &filter ) ;

//... do the process stuff ...

removeEventFilter( &filter );

restoreOverrideCursor();
4 голосов
/ 06 января 2010

Чтобы получить полный доступ к событиям всего приложения, используйте QObject::installEventFilter() или QCoreApplication::setEventFilter() в объекте приложения.
Если ваша функция фильтра возвращает true, Qt останавливает дальнейшую обработку события.

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

1 голос
/ 06 января 2010

В качестве альтернативного ответа вы можете создать свой собственный цикл обработки событий и запустить его при необходимости. Вам нужно будет создать объект QEventLoop, подключить сигнал от другого процесса к его quit() слоту (например, к QProcess, в котором вы запускаете другую программу), затем exec() петля. Если я правильно читаю, ваш главный цикл обработки событий не будет обрабатывать ничего, пока этот цикл выполняется.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...