Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to send artificial QKeyEvent to QWebEngineView?

Context: I'm creating a small web browser with a custom on-screen keyboard.

It was working almost fine with Qt WebKit (QWeb* classes) but there were crashes attributed to bugs in WebKit... which won't be fixed after Qt 5.4.0 since they're moving to Qt WebEngine.

So I decided to move the stuff to Qt WebEngine (QWebEngine* classes), following the short webkit->webengine transition guide. Following the caveat section on QWebElement, I have worked my way around showing/hiding the on-screen keyboard (which now requires running async. JS code). But I'm scratching my head on how to send artificial key events to the web page.

I have tried the some stuff:

  • QCoreApplication::postEvent(m_webview, event) doesn't do anything, when it was working with the old QWeb stuff;
  • It's possible to send keys by running JavaScript but I find this too dirty

Thanks,

like image 257
cJ Zougloub Avatar asked Jan 12 '15 03:01

cJ Zougloub


3 Answers

This code work fine

 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);
    }
like image 161
magrif Avatar answered Oct 15 '22 12:10

magrif


I guess the only possibility to achieve this right now would be to make use of QAction to send an event to the WebView by using for example something like that:

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

I suppose the functionality will be added in Qt 5.5.1 as you can see below:

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

like image 38
deW1 Avatar answered Oct 15 '22 14:10

deW1


Despite original question is one year old, it is still actual for those who like me decided to move (at last!) from QWebKit to QWebEngine (Qt 5.5 - 5.6b). Here is a dirty solution that requires existing webenginepage->view(). This is for mouse events, and it would not be a big surprise if it's not situated for keyboard events:

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 );
}

Inspired by Using QWebEngine to render an image and How can I get paint events with QtWebEngine? and googling.

like image 44
sendevent Avatar answered Oct 15 '22 12:10

sendevent