Reputation: 432
System: Qt/QML 5.3.1 Android with Windows QtCreator Device: Samsung Tab 3 8", with Android 4.1.2
EDIT: My Main QML page contains a TextInput with Keys.onPressed. This TextInput receives only the DEL key and not other keys from standard virtual keyboard.
How to do to receive all keys in the TextInput/Keys.onPressed event handler?
import QtQuick 2.2
import QtQuick.Window 2.1
import QtQuick.Controls 1.2
ApplicationWindow {
visible: true
width: 640
height: 400
toolBar: ToolBar {
Row {
anchors.fill: parent
ToolButton {
text: "Exit"
onClicked: Qt.quit();
}
}
}
TextInput {
width: 200
height: 40
focus: true
Keys.onPressed: {
console.log("Key="+event.key+" "+event.text);
}
Keys.onReleased: {
console.log("Key="+event.key+" "+event.text);
}
}
}
An error is raised by Qt when I'm pressing a key on virtual keyboard, including the DEL key:
W/Qt (26304): kernel\qmetaobject.cpp:1458 (static bool QMetaObject::invokeMethod(QObject*, const char*, Qt::ConnectionType, QGenericReturnArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument)): QMetaObject::invokeMethod: No such method QQuickTextInput::inputMethodQuery(Qt::InputMethodQuery,QVariant)
EDIT (27.10.2014): This problem occurs because it is a missing functionality in Qt/Qml, see the following link for discussion about it http://qt-project.org/forums/viewthread/45072/ and the following link for the report to Qt https://bugreports.qt-project.org/browse/QTBUG-40803
Upvotes: 3
Views: 3112
Reputation: 16819
As the question author already found, this problem is due to missing functionality in Qt for Android (see QTBUG-40803):
On Samsung devices, like tablets and smartphones, it is impossible to receive keys from the virtual keyboard [from a TextInput component], by using
Keys.onPressed
orKeys.onRelease
, except for DEL and ENTER keys.
The issue is not limited to Samsung devices as told in the bug report; it's also happening on my Asus Nexus 7, for example. The DEL key mentioned in the bug report is the key ⌫ (Delete / Backspace) of the Android keyboard, not Delete (which the Android keyboard does not have). The key events for this key are not emitted every time, but only when pressed in an empty TextField.
This behavior is different from Qt desktop applications, where every keypress / key release event of a physical key is signaled by TextInput.
You cannot listen to Keys.onPressed
/ Keys.onReleased
, but you can listen to the onTextEdited
and onTextChanged
signals of TextInput
. For simple cases like to enable a button when the field contains text, these signals are enough. For other cases, you could analyze what text was typed and take action based on the key used for that.
This solution is further complicated by two other bugs:
On the Android platform, the textChanged()
and textEdited()
signals are not emitted by TextInput
as long as predictive text input is enabled for the Android keyboard (source). I suppose they are emitted eventually but only after "committing" a word by typing the space character or tapping on a suggestion. That does not help if you want to react to key presses, of course. So you first have to disable predictive text input behavior with TextInput { inputMethodHints: Qt.ImhNoPredictiveText }
.
On some devices, TextInput { inputMethodHints: Qt.ImhNoPredictiveText }
has no effect (QTBUG-37533). Then, inputMethodHints: Qt.ImhSensitiveData
is an alternative. Works on Asus 7. (This does not create a "password entry field" – text will still be shown in the field, but predictive input etc. is switched off.)
Taken together, a working solution (for me on Nexus 7) looks like this:
TextField {
inputMethodHints: Qt.ImhSensitiveData
onTextEdited: {
console.log("textEdited() signal received")
}
Upvotes: 1