qtqmlqt5qtwebengineqwebengineview

WebEngineView getting text input focus


How can I detect focus on the text field (input) on the webpage displayed using QML WebEngineView?

I need this information to display/hide the virtual keyboard.


Solution

  • To getting text input focus on the webpage displayed via QML WebEngineView required is use WebChannel and run some js code on your webpage. You don't need to modify the page source.

    QML side:

    import QtWebEngine 1.5
    import QtWebChannel 1.0
    ...
    QtObject{
        id: someObject
        WebChannel.id: "backend"
    
        function showKeyboard() {
            console.log("Show the keyboard");
            inputEngine.showLiteralKeyboard = true
        }
        function hideKeyboard() {
            console.log("Hide the keyboard");
            inputEngine.hide()
        }
    }
    
    WebEngineView{
        id: webview
        url: "https://your-webpage.com/"
        anchors.fill: parent
        settings.javascriptEnabled: true
        webChannel: channel
    
        onLoadingChanged: {
            if(loadRequest.status === WebEngineView.LoadSucceededStatus){
                webview.runJavaScript(systemManager.qwebchannelSource())
                webview.runJavaScript("
                    new QWebChannel(qt.webChannelTransport, function(channel){
                        var backend = channel.objects.backend;
                        var inputs = document.getElementsByTagName('input');
                        var index;
    
                        for(index=0; index < inputs.length; index++)
                        {
                            inputs[index].onfocus = function(){
                                backend.showKeyboard()
                            };
                            inputs[index].onblur = function(){
                                backend.hideKeyboard()
                            }
                        }
                    })")
            }
        }
    }
    
    WebChannel{
        id: channel
        registeredObjects: [someObject]
    }
    ...
    

    systemmanager.cpp: Contains function to load and expose qwebchannel.js source:

    ...
    QString SystemManager::qwebchannelSource()
    {
        QFile qwebchannelFile(":/qtwebchannel/qwebchannel.js");     // Load the JS API from the resources
        if(!qwebchannelFile.open(QIODevice::ReadOnly)){
            qDebug()<<"Couldn't load Qt's QWebChannel API!";
        }
    
        QString scriptSource = QString::fromLatin1(qwebchannelFile.readAll());
        qwebchannelFile.close();
    
        return scriptSource;
    }
    ...
    

    systemManager.h Header part with exposing function:

    ...
    Q_INVOKABLE QString qwebchannelSource();
    ...
    

    NOTE: The SystemManager object must be exposed to QML.