我有一个虚拟键盘,从屏幕底部弹出并始终保持在顶部。我将在我的应用程序中使用它并遇到一个小问题。
如果接受来自此键盘的输入的文本输入字段位于视图的中间/底部(主窗口/屏幕),则它隐藏在键盘后面,即,在键盘被隐藏之前无法看到输入的内容。
键盘正在作为platforminputcontext
插件运行,它将知道接受输入的字段。
void KeyboardPlatformInputContext::setFocusObject(QObject* object)
{
qDebug() << m_focusedObject << object;
m_focusedObject = object;
}
按下键时,它们会像QEvents
那样传递
void KeyboardPlatformInputContext::processNormalKeyClick(const QString& key)
{
qDebug() << m_focusedObject << key;
if (m_focusedObject) {
QInputMethodEvent inputEvent;
inputEvent.setCommitString(key);
QGuiApplication::sendEvent(m_focusedObject, &inputEvent);
}
}
现在,通过可用信息(m_focusedObject
和QGuiApplication
),可以做一些事情来保持输入字段的可见性。总是
答案 0 :(得分:2)
库巴有正确的想法;我会扩展它。例如,您可以使用Flickable
来管理应用程序的内容。例如,假设您的应用程序布局如下:
import QtQuick 2.0
import QtQuick.Window 2.0
Window {
id: root
width: 480
height: 800
visible: true
Column {
anchors.fill: parent
anchors.margins: 20
spacing: 20
Repeater {
model: 20
Row {
spacing: 20
Text {
text: "Input #" + (index + 1)
anchors.verticalCenter: parent.verticalCenter
}
TextInput {
width: 100
height: 30
onActiveFocusChanged: {
if (activeFocus)
keyboardRect.visible = activeFocus
}
Rectangle {
border.width: 1
anchors.fill: parent
anchors.margins: -1
z: -1
}
}
}
}
}
Rectangle {
id: keyboardRect
width: parent.width
height: parent.height * 0.3
anchors.bottom: parent.bottom
color: "grey"
visible: false
}
}
要使其可用于虚拟键盘,请将内容移至Flickable
:
import QtQuick 2.0
import QtQuick.Window 2.0
Window {
id: root
width: 480
height: 800
visible: true
Flickable {
id: flickable
anchors.fill: parent
anchors.margins: 20
anchors.bottomMargin: keyboardRect.visible ? keyboardRect.height : anchors.margins
contentWidth: column.implicitWidth
contentHeight: column.implicitHeight
flickableDirection: Flickable.VerticalFlick
Column {
id: column
spacing: 20
Repeater {
model: 20
Row {
spacing: 20
Text {
text: "Input #" + (index + 1)
anchors.verticalCenter: parent.verticalCenter
}
TextInput {
width: 100
height: 30
onActiveFocusChanged: {
if (activeFocus) {
keyboardRect.visible = activeFocus
var posWithinFlickable = mapToItem(column, 0, height / 2);
flickable.contentY = posWithinFlickable.y - flickable.height / 2;
}
}
Rectangle {
border.width: 1
anchors.fill: parent
anchors.margins: -1
z: -1
}
}
}
}
}
}
Rectangle {
id: keyboardRect
width: parent.width
height: parent.height * 0.3
anchors.bottom: parent.bottom
color: "grey"
visible: false
}
}
有几点需要注意:
anchors.bottomMargin: keyboardRect.visible ? keyboardRect.height : anchors.margins
这可确保在键盘可见时“推”内容,以便在其下方不会隐藏任何内容。
onActiveFocusChanged: {
if (activeFocus) {
keyboardRect.visible = activeFocus
var posWithinFlickable = mapToItem(column, 0, height / 2);
flickable.contentY = posWithinFlickable.y - flickable.height / 2;
}
}
此代码不会导致失去焦点,因此键盘始终保持打开状态。
我们将Flickable
的焦点放在当前输入字段上,方法是将字段的位置映射到Column
。
最后,当您点击列顶部或底部附近的字段时,您会看到一些跳跃。如果字段靠近顶部或底部,则可以通过不设置contentY
来解决此问题。为读者练习。 :)
答案 1 :(得分:0)
对我来说,正确的答案是上面(第一个)加上以下内容:
https://doc.qt.io/qt-5/qtvirtualkeyboard-deployment-guide.html#creating-inputpanel
import QtQuick 2.0
import QtQuick.VirtualKeyboard 2.1
Item {
id: root
Item {
id: appContainer
anchors.left: parent.left
anchors.top: parent.top
anchors.right: parent.right
anchors.bottom: inputPanel.top
...
}
InputPanel {
id: inputPanel
y: Qt.inputMethod.visible ? parent.height - inputPanel.height : parent.height
anchors.left: parent.left
anchors.right: parent.right
}
}
报价:
输入面板必须是应用程序旁边的同级元素 容器。重要的是不要将输入面板放在 应用程序容器,因为它将与以下内容重叠 应用程序。此外,输入面板的高度将自动 根据可用宽度进行更新;的长宽比 输入面板是恒定的。