- PVSM.RU - https://www.pvsm.ru -
В данной статье я попытаюсь рассказать о том как передавать события мыши и клавиатуры в QQuickWindow [1], в случае его использования в связке с QQuickRenderControl [2]. Причиной того, что этому необходимо уделять специальное внимание, является то, что в случае использования QQuickRenderControl, никакого окна на самом деле не создается, соответственно у QQuickWindow нет абсолютно никакой возможности получать какие либо события, и их приходится эмулировать. То же самое касается изменения размеров — об этой операции так же необходимо оповещать в явном виде.
Для тех кто пропустил предыдущие части:
Отправка события в Qt осуществляется с помощью метода
bool QCoreApplication::sendEvent(QObject* receiver, QEvent* event)
где,
Для корректного функционирования достаточно реализовать 3 события мыши:
QEvent::MouseButtonPress:
QPointF mousePoint( 150, 201 );
Qt::MouseButton button = Qt::LeftButton;
Qt::MouseButton buttons = Qt::LeftButton | Qt::RightButton;
Qt::KeyboardModifiers modifiers = Qt::AltModifier;
QMouseEvent mouseEvent( QEvent::MouseButtonPress, mousePoint, mousePoint, button, buttons, modifiers );
QCoreApplication::sendEvent( quickWindow, &mouseEvent );
где,
mousePoint используется дважды, поскольку в первый раз передается в координатах QQuckWindow, второй раз в screen координатах. Но поскольку окно на самом не создается, трактуется всегда как окно верхнего уровня, и его позицией мы управляем самостоятельно, то передаем одно и то же значение (как будто окно находится всегда в верхнем левом углу экрана), а при установке позиции окна, просто будем этот факт учитывать.
QEvent::MouseMove:
QPointF mousePoint( 170, 198 );
Qt::MouseButton button = Qt::NoButton;
Qt::MouseButton buttons = Qt::LeftButton | Qt::RightButton;
Qt::KeyboardModifiers modifiers = Qt::AltModifier;
QMouseEvent mouseEvent( QEvent::MouseMove, mousePoint, mousePoint, button, buttons, modifiers );
QCoreApplication::sendEvent( quickWindow, &mouseEvent );
Поскольку причиной события передвижения мыши является сам факт передвижения мыши, а не какая-либо из кнопок, переменной button присваивается значение Qt::NoButton.
QEvent::MouseButtonRelease:
QPointF mousePoint( 160, 251 );
Qt::MouseButton button = Qt::LeftButton;
Qt::MouseButton buttons = Qt::LeftButton;
Qt::KeyboardModifiers modifiers = Qt::AltModifier;
QMouseEvent mouseEvent( QEvent::MouseButtonRelease, mousePoint, mousePoint, button, buttons, modifiers );
QCoreApplication::sendEvent( quickWindow, &mouseEvent );
button в данном случае означает кнопку являвшуюся причиной данного события, но в данном случае кнопка была отпущена, соответственно buttons она присутствовать уже не может (иначе Qt начинает обрабатывать это событие неверно).
Аналогично, для корректной обработки событий клавиатуры, достаточно реализовать 2 события:
QEvent::KeyPress:
Qt::Key qtKey = Qt::Key_Space;
QKeyEvent keyEvent( QEvent::KeyPress, qtKey, Qt::NoModifier );
QCoreApplication::sendEvent( quickWindow, &keyEvent );
QEvent::KeyRelease:
Qt::Key qtKey = Qt::Key_Space;
QKeyEvent keyEvent( QEvent::KeyRelease, qtKey, Qt::NoModifier );
QCoreApplication::sendEvent( quickWindow, &keyEvent );
Как уже упомяналось выше, offscreen окна в Qt трактутся как окна верхнего уровня, поэтому используем соответствующий метод:
QSize newSize( 320, 240 );
quickWindow->setGeometry( 0, 0, newSize.width(), newSize.height() );
Помимо изменения размеров собственно окна, желательно так же изменить размеры FBO, т.к. в противном случае либо получим пикселизацию (при увеличении размера), либо бессмысленное расходование ресурсов (т.к. размер FBO будет больше чем требуется):
if( context->makeCurrent( offscreenSurface ) ) {
destroyFbo();
createFbo();
context->doneCurrent();
}
Поскольку изменить размер FBO невозможно, просто удаляем текущий и создаем новый ( см. детали в Первой части [5] ).
На этом все.
Примеры реализации, как обычно, доступены на GitHub [6]
Ну и как и прежде, коментарии, вопросы, здоровая критика — приветствуются.
Продолжение следует...
Автор: RSATom
Источник [7]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/programmirovanie/81273
Ссылки в тексте:
[1] QQuickWindow: http://doc.qt.io/qt-5/qquickwindow.html
[2] QQuickRenderControl: http://doc.qt.io/qt-5/qquickrendercontrol.html
[3] Часть I: http://habrahabr.ru/post/247477
[4] Часть II: http://habrahabr.ru/post/248103
[5] Первой части: http://habrahabr.ru/post/247477/
[6] GitHub: https://github.com/RSATom/WebChimera/blob/master/src/Mac/Chimera_Mac.mm#L176
[7] Источник: http://habrahabr.ru/post/249383/
Нажмите здесь для печати.