[Solved] How to detect HTML text input field gets focus in a QML WebView



  • I have an embedded Linux device with touch screen only.
    My app is C++ and QML, currently QtQuick 1.1 but thinking about porting to QtQuick 2.0.

    I made an iPad like virtual keyboard that slides in from the bottom, which sends key-events from C++ to QML. This one works fine with the standard QML components. When a QML textfield gets focus, I show my keyboard and I can type.

    Now I also want to include a simple web-browser in my App.
    I need to be able to detect that a textfield (HTML input, etc) has received/lost focus, so that I can show or hide my virtual keyboard.

    I tried the onFocusChanged (and onActiveFocusChanged) of the WebView but that turned out not what I need, since that will trigger when the complete WebView gets focus (also when clicking a link, image, etc).

    Note, I want to show content of which I cannot change the HTML code (e.g. google)

    How can I detect that focus has been changed on an HTML input field?



  • I would try to use a bridge between native code and javascript in the html page.
    http://qt-project.org/doc/qt-5.0/qtwebkit/qtwebkit-bridge.html

    You just need a method to be fired when you get focus in the HTML input, and that method is then communicating to the webview which in turn lets your keyboard get notified.



  • Thanks for your reply.

    I know about the web bridge see my "posting":http://qt-project.org/forums/viewthread/25576/.
    I am not sure that the bridge also works on a qml web view though. I used it on a Qt webview widget in the past only.

    The real issue I face is detecting the html input getting focus.

    Any idea how I can do that?





  • Yes that may work if I have control over the content of the HTML.
    The pages are however not my own, e.g. google.com.

    So I'm looking for some kind of trigger from the WebView itself when an input is selected.





  • With your tips and some other posts I managed to solve it in QML only.
    Not sure if it will work on a QtWebKit 3.0 once I port to QtQuick 2.0, but on QtQuick 1.1 and QtWebKit 1.0 it works.

    This is what I did in my WebView:
    @
    WebView {
    ......
    settings.javaEnabled: true
    javaScriptWindowObjects: QtObject {
    WebView.windowObjectName: "qml"

            function showKeyboard() {
                console.log("Show the keyboard");
            }
            function hideKeyboard() {
                console.log("Hide the keyboard");
            }
    
        }
    
        onLoadFinished: {
                       webView.evaluateJavaScript("var inputs = document.getElementsByTagName('INPUT');var index;for(index=0; index < inputs.length; index++){inputs[index].onfocus = function() {window.qml.showKeyboard()};inputs[index].onblur = function() {window.qml.hideKeyboard()}}")
        }
    

    .....
    }
    @



  • Hi All,
    I follow your steps, and my virtual keyboard come out correctly.
    My problem is to pass the edited text back to the page.
    I modified the showKeyboard to save the id and the value of the text field, so I can manipulate it.

    I added the following on close of the virtual keyboard (custom):
    @
    onUpdate_text:{
    chiudi_tastiera();
    webView.evaluateJavaScript("var inputs = document.getElementsByTagName('INPUT');var element = inputs["+ GlobalJS.indice_in_text +"];element.value = '"+ GlobalJS.editor_text +"'}")
    }
    @
    But I have no text in the field.... I'm testing it with the search field of Google.com

    Do you have idea why?

    Thanks a lot for your help
    Dario



  • You should have made another topic of this question, this topic is already marked as solved. And be patience, I did't like receiving a private email asking for an answer.

    Anyhow, I'm glad that my piece of code helped you get your keyboard to appear.

    My keyboard works differently. It uses C++ to send KeyEvents so standard QML components see it is a 'real' keyboard.

    Your info is a bit limited so I can honestly not say what is wrong in your case.
    Did you check if your onUpdate_text is called, is the value of the indice_in_text and editor_text correct. Did you try if 'hard-coding' the index and the text you, to see if that does work.

    If your script in evaluateJavaScript has an error, you do not see that in the Qt console. You could use the Web-inspector for that (need to right-click so attach a mouse to your target if possible or run your app on a PC).

    Add the following to your webview:
    @
    settings.developerExtrasEnabled: true
    @

    When you start the program right click on the web-page and select 'inspect'. In the console tab you can see the output of your javascript in the webpage, and so you can check for errors.

    I tried the following (for test I use a hardcoded index specific for the input field of google.com page) and that works.
    Hello appears in the google search bar
    @
    import QtQuick 1.1
    import QtWebKit 1.0

    Rectangle {
    width: 800
    height: 800

    WebView {
        id: webView
        settings.javaEnabled: true
        settings.developerExtrasEnabled: true
        anchors.fill: parent
        url: "http://www.google.com/"
        onLoadFinished: {
            webView.evaluateJavaScript("var inputs = document.getElementsByTagName('INPUT'); var element = inputs[2]; element.value='Hello'")
        }
    }
    

    }
    @

    So it looks like the general idea of your Script can work. It may be the GlobalJS stuff that you save. If that is a shared JavaScript file between different QML files, don't forget to add to that .js file
    @
    .pragma library
    @

    to make sure the value of your variables are shared between the QML files.

    I hope that this helps you in the right direction.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.