Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

QML virtual keyboard dimensions

I'm having trouble finding the dimensions for the virtual keyboard. Here's an example:

Rectangle {
    Component.onCompleted: {
        Qt.inputMethod.visibleChanged.connect(resizeForKeyboard)
    }

    Component.onDestruction: {
        Qt.inputMethod.visibleChanged.disconnect(resizeForKeyboard)
    }

    function resizeForKeyboard(){
        console.log('Visibility changed!!!');
        var keys = Object.keys(Qt.inputMethod.keyboardRectangle);
        var rect = Qt.inputMethod.keyboardRectangle;
        //A simple script I have for debugging, this loops 
        //through the keys and prints all properties
        DataMethods.printObject(keys, '[INPUT]');
        DataMethods.printObject(rect , '[RECTANGLE]');
    }

    //using the controls to save time
    TextField {
      focus: true //force keyboard to show up.
    }
}

datamethods.js (relevant method)

/**
 * This method prints an object to the console for debug purposes
 * obj -> the objec to print
 * prefix -> the prefix to append "[prefix] -> "...
 * props -> a list of properties to use, otherwiese all will be printed
 */
function printObject(obj, prefix, props) {
    if(!prefix)
        prefix = "obj";

    if(obj){
        console.log(prefix + obj + "->" + typeof obj);
        if(props){
            for(var p in obj)
                console.log('\t' + prefix + "["+ p + "] -> '" + obj[p] + "'");
        } else {
            for(var p in obj)
                console.log('\t' + prefix + "["+ p + "] -> '" + obj[p] + "'");
        }
    } else {
        console.log(prefix + "is null");
    }
}

Here's the output:

[INPUT]objectName,cursorRectangle,keyboardRectangle,visible,animating,locale,inputDirection,destroyed,destroyed,objectNameChanged,deleteLater,_q_reregisterTimers,cursorRectangleChanged,keyboardRectangleChanged,visibleChanged,animatingChanged,localeChanged,inputDirectionChanged,show,hide,update,reset,commit,invokeAction->object
D/Qt      (30122): qrc:js/datamethods.js:153 (printObject):     [INPUT][0] -> 'objectName'
D/Qt      (30122): qrc:js/datamethods.js:153 (printObject):     [INPUT][1] -> 'cursorRectangle'
D/Qt      (30122): qrc:js/datamethods.js:153 (printObject):     [INPUT][2] -> 'keyboardRectangle'
D/Qt      (30122): qrc:js/datamethods.js:153 (printObject):     [INPUT][3] -> 'visible'
D/Qt      (30122): qrc:js/datamethods.js:153 (printObject):     [INPUT][4] -> 'animating'
D/Qt      (30122): qrc:js/datamethods.js:153 (printObject):     [INPUT][5] -> 'locale'
D/Qt      (30122): qrc:js/datamethods.js:153 (printObject):     [INPUT][6] -> 'inputDirection'
D/Qt      (30122): qrc:js/datamethods.js:153 (printObject):     [INPUT][7] -> 'destroyed'
D/Qt      (30122): qrc:js/datamethods.js:153 (printObject):     [INPUT][8] -> 'destroyed'
D/Qt      (30122): qrc:js/datamethods.js:153 (printObject):     [INPUT][9] -> 'objectNameChanged'
D/Qt      (30122): qrc:js/datamethods.js:153 (printObject):     [INPUT][10] -> 'deleteLater'
D/Qt      (30122): qrc:js/datamethods.js:153 (printObject):     [INPUT][11] -> '_q_reregisterTimers'
D/Qt      (30122): qrc:js/datamethods.js:153 (printObject):     [INPUT][12] -> 'cursorRectangleChanged'
D/Qt      (30122): qrc:js/datamethods.js:153 (printObject):     [INPUT][13] -> 'keyboardRectangleChanged'
D/Qt      (30122): qrc:js/datamethods.js:153 (printObject):     [INPUT][14] -> 'visibleChanged'
D/Qt      (30122): qrc:js/datamethods.js:153 (printObject):     [INPUT][15] -> 'animatingChanged'
D/Qt      (30122): qrc:js/datamethods.js:153 (printObject):     [INPUT][16] -> 'localeChanged'
D/Qt      (30122): qrc:js/datamethods.js:153 (printObject):     [INPUT][17] -> 'inputDirectionChanged'
D/Qt      (30122): qrc:js/datamethods.js:153 (printObject):     [INPUT][18] -> 'show'
D/Qt      (30122): qrc:js/datamethods.js:153 (printObject):     [INPUT][19] -> 'hide'
D/Qt      (30122): qrc:js/datamethods.js:153 (printObject):     [INPUT][20] -> 'update'
D/Qt      (30122): qrc:js/datamethods.js:153 (printObject):     [INPUT][21] -> 'reset'
D/Qt      (30122): qrc:js/datamethods.js:153 (printObject):     [INPUT][22] -> 'commit'
D/Qt      (30122): qrc:js/datamethods.js:153 (printObject):     [INPUT][23] -> 'invokeAction'
D/Qt      (30122): qrc:js/datamethods.js:147 (printObject): [RECTANGLE]QRectF(0, 0, 0, 0)->object

I might be going about this the totally wrong way and I would love a way to handle it. The reason I need the size of the keyboard on the device is so I can respond in my UI and not bury controls below it (so the user can continue to scroll through the form).

As you can see the keyboardRectangle property of Qt.inputMethod appears to be default values.

Where should I be retrieving this information, the signal seems correct as it fires on open/close of the virtual keyboard?

like image 815
Daniel B. Chapman Avatar asked Feb 25 '14 23:02

Daniel B. Chapman


1 Answers

I was able to get the virtual keyboard dimensions by using QDesktopWidget::availableGeometry(); to get the usable screen size, QDesktopWidget::screenGeometry(); to get the fullscreen dimensions and a little bit of Java code to get the menubar size.

And here are the most relevant parts of the code:

C++ side:

QRect KeyboardInterface::rect()
{
    int menuheight = (int)QAndroidJniObject::callStaticMethod<jint>("org.qtproject.example.Demo2.JavaInterface", "getHeight");

    QDesktopWidget widget;
    QRect rect = widget.availableGeometry();
    QRect geom = widget.screenGeometry();

    rect.moveTop(rect.top() + menuheight);
    geom.setTop(geom.top() + menuheight);

    QRect final;

    if (rect != geom)
    {
        int ftop, fleft, fwidth, fheight;

        geom.getRect(&fleft, &ftop, &fwidth, &fheight);

        if (rect.top() != ftop)
            fheight = rect.top();
        else if (rect.left() != fleft)
            fwidth = rect.left();
        else if (rect.height() != fheight)
            ftop = rect.height();
        else if (rect.width() != fwidth)
            fleft = rect.width();

        final = QRect(fleft, ftop, fwidth - fleft, fheight - ftop);
    }

    return final;
}

Java side:

package org.qtproject.example.Demo2;

import android.app.Activity;
import android.graphics.Rect;
import android.view.View;
import android.view.Window;

public class JavaInterface extends org.qtproject.qt5.android.bindings.QtActivity
{
    private static JavaInterface instance;

    public JavaInterface()
    {
        instance = this;
    }

    public static int getHeight()
    {
        Rect r = new Rect();
        Window window = instance.getWindow();
        View rootview = window.getDecorView();
        rootview.getWindowVisibleDisplayFrame(r);

        return r.top;
    }
}

A full source code of this project can be found here

Hope that helps.

like image 50
Antonio Dias Avatar answered Oct 16 '22 11:10

Antonio Dias