Qt 使用屏幕键盘时,保持输入字段在视图中

Qt 使用屏幕键盘时,保持输入字段在视图中,qt,qml,Qt,Qml,我有一个虚拟键盘,它从屏幕底部弹出,并始终保持在顶部。我将在我的应用程序中使用它,但有一个小问题 如果接受此键盘输入的文本输入字段位于视图(主窗口/屏幕)的中间/底部,则它会隐藏在键盘后面,即在隐藏键盘之前无法看到输入的内容 键盘作为platforminputcontext插件运行,该插件将知道接受输入的字段 void KeyboardPlatformInputContext::setFocusObject(QObject* object) { qDebug() << m_f

我有一个虚拟键盘,它从屏幕底部弹出,并始终保持在顶部。我将在我的应用程序中使用它,但有一个小问题

如果接受此键盘输入的文本输入字段位于视图(主窗口/屏幕)的中间/底部,则它会隐藏在键盘后面,即在隐藏键盘之前无法看到输入的内容

键盘作为
platforminputcontext
插件运行,该插件将知道接受输入的字段

void KeyboardPlatformInputContext::setFocusObject(QObject* object)
{
    qDebug() << m_focusedObject << object;
    m_focusedObject = object;
}

现在,有了可用的信息(
m_focusedObject
QGuiApplication
),就可以做一些事情来保持输入字段在视图中。永远。

库巴有正确的想法;我会详细介绍一下。例如,您可以使用来管理应用程序的内容。例如,假设您的应用程序的布局类似于表单:

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
集中在当前输入字段上


最后,当您单击列顶部或底部附近的字段时,您将看到一些跳跃。如果字段接近顶部或底部,则不设置
内容
,可能可以解决此问题。给读者的练习。:)

对我来说,正确答案在上面(第一个)加上以下内容:

引用:

输入面板必须是应用程序旁边的同级元素 容器。重要的是不要将输入面板放在 应用程序容器,因为它将与 应用程序。此外,输入面板的高度将自动调整 根据可用宽度进行更新;的纵横比 输入面板是恒定的


首先,您需要一种机制来移动整个UI。您必须弄清楚在您的特定用例中什么将起作用。然后用它移动物体,使聚焦控件可见(如果不是从一开始)。对我来说,正确答案是你的加上以下内容:
onActiveFocusChanged: {
    if (activeFocus) {
        keyboardRect.visible = activeFocus

        var posWithinFlickable = mapToItem(column, 0, height / 2);
        flickable.contentY = posWithinFlickable.y - flickable.height / 2;
    }
}
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
    }
}