Как отправить искусственный QKeyEvent в QWebEngineView?

Контекст: я создаю небольшой веб-браузер с пользовательской экранной клавиатурой.

Он работал почти отлично с Qt WebKit (QWeb* classes), но произошли сбои, связанные с ошибками в WebKit... которые не будут исправлены после Qt 5.4.0, поскольку они переходят на Qt WebEngine.

Итак, я решил переместить материал в Qt WebEngine (QWebEngine* classes), следуя краткому руководству по переходу webkit- > webengine. Следуя разделу оговорки QWebElement, я проработал способ показать/скрыть экранную клавиатуру (в которой теперь требуется запуск async. JS-кода). Но я почесываю голову, как отправлять события искусственного ключа на веб-страницу.

Я пробовал некоторые вещи:

  • QCoreApplication::postEvent(m_webview, event) ничего не делает, когда он работает со старыми вещами QWeb;
  • Можно отправить ключи, запустив JavaScript, но я считаю это слишком грязным

Спасибо,

Ответ 1

Я предполагаю, что единственная возможность достичь этого прямо сейчас будет заключаться в том, чтобы используйте QAction для отправки события в WebView, используя, например, что-то вроде этого:

connect( this , SIGNAL( keyPressed( int ) ) , &m_webview , SLOT( handleKey( int ) ) );

Я полагаю, что функциональность будет добавлена ​​в Qt 5.5.1, как вы можете видеть ниже:

https://codereview.qt-project.org/#/c/104901/

Ответ 2

Несмотря на то, что первоначальный вопрос - один год, он по-прежнему актуальен для тех, кто, как я, решил переехать (наконец!) из QWebKit в QWebEngine (Qt 5.5 - 5.6b). Вот грязное решение, которое требует существующей webenginepage- > view(). Это для событий мыши, и это не было бы большим сюрпризом, если бы он не был расположен для событий клавиатуры:

void Whatever::sendMouseEvent( QObject* targetObj, QMouseEvent::Type type, const QPoint& pnt ) const
{
    QMouseEvent event( type, pnt, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier );
    QApplication::sendEvent( targetObj, &event );
}

void Whatever::sendMouseClick( QObject* targetObj, const QPoint& pnt ) const
{
    sendMouseEvent( targetObj, QMouseEvent::MouseMove, pnt );
    sendMouseEvent( targetObj, QMouseEvent::MouseButtonPress, pnt );
    sendMouseEvent( targetObj, QMouseEvent::MouseButtonRelease, pnt );
}

void Whatever::emulateMouseClick( const QPoint& pnt ) const
{
    //-- right now (Qt 5.5 & 5.6) there is only one child - 
    //-- QtWebEngineCore::RenderWidgetHostViewQtDelegateWidget
    //-- but it could change in future
    Q_FOREACH( QObject* obj, mWebEnPage->view()->children() ) //-- ACHTUNG! Check mWebEnPage->view() in real code!
        if( qobject_cast<QWidget*>( obj ) )
            sendMouseClick( obj, pnt );
}

Вдохновленный Использование QWebEngine для рендеринга изображения а также Как я могу рисовать события с помощью QtWebEngine? и googling.

Ответ 3

Этот код работает нормально

 for(auto* child : ui->webEngineView->children() ) {
        int key = Qt::Key_V; //or some other
        QKeyEvent pressEvent = QKeyEvent(QEvent::KeyPress, key, Qt::NoModifier, QKeySequence(key).toString());
        QKeyEvent releaseEvent = QKeyEvent(QEvent::KeyRelease, key, Qt::NoModifier);
        qApp->sendEvent(child, &pressEvent);
        qApp->sendEvent(child, &releaseEvent);
    }