QML virtual keyboard dimensions
android, keyboard, qml, qt, qt5
Solution
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.
Problem
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?