系统:Qt/QML 5.3.1 Android with Windows QtCreator设备:三星Tab 3 8", Android 4.1.2
编辑:我的主QML页面包含一个带有Keys.onPressed的TextInput。这个TextInput只接收DEL键,而不接收来自标准虚拟键盘的其他键。
如何接收TextInput/keys中的所有键。onPressed事件处理程序?
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);
}
}
}
当我在虚拟键盘上按下一个键时,Qt会抛出一个错误,包括DEL键:
W/Qt(26304):内核 QMetaObject .cpp:1458(静态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)
编辑 (27.10.2014):出现此问题是因为它是Qt/Qml中缺少的功能,请参阅以下链接以了解有关它的讨论http://qt-project.org/forums/viewthread/45072/和Qt报告的以下链接https://bugreports.qt-project.org/browse/QTBUG-40803
分析
正如问题作者已经发现的那样,这个问题是由于Android Qt缺少功能(见QTBUG-40803):
在三星设备上,如平板电脑和智能手机,不可能通过使用
Keys.onPressed
或Keys.onRelease
从虚拟键盘[从TextInput组件]接收键,除了DEL和ENTER键。
这个问题并不局限于三星设备,正如在bug报告中所说的;例如,我的华硕Nexus 7也是如此。bug报告中提到的DEL键是Android键盘的键(Delete/Backspace),而不是Delete键(Android键盘没有这个功能)。此键的键事件不是每次都触发,而只在空TextField中按下时触发。
此行为与Qt桌面应用程序不同,在Qt桌面应用程序中,物理键的每个按键/键释放事件都由TextInput发出信号。
解决方案无法收听Keys.onPressed
/Keys.onReleased
,但可以收听TextInput
的onTextEdited
和onTextChanged
信号。对于简单的情况,比如当字段包含文本时启用按钮,这些信号就足够了。对于其他情况,您可以分析键入的文本并根据所使用的键采取操作。
这个解决方案由于另外两个错误而更加复杂:
在Android平台上,只要Android键盘启用了预测文本输入,
textChanged()
和textEdited()
信号就不会由TextInput
发出(源)。我想它们最终会被释放但只在"承诺"之后通过键入空格字符或点击提示来输入单词。当然,如果你想对按键做出反应,这是没有帮助的。因此,您首先必须禁用TextInput { inputMethodHints: Qt.ImhNoPredictiveText }
的预测文本输入行为。在某些设备上,
TextInput { inputMethodHints: Qt.ImhNoPredictiveText }
没有效果(QTBUG-37533)。那么,inputMethodHints: Qt.ImhSensitiveData
是另一种选择。适用于华硕7。(这不会创建"密码输入字段";-文本仍将显示在字段中,但预测输入等被关闭。)
总的来说,一个可行的解决方案(对我来说是在Nexus 7上)是这样的:
TextField {
inputMethodHints: Qt.ImhSensitiveData
onTextEdited: {
console.log("textEdited() signal received")
}