使用屏幕键盘时,保持输入字段可见

ram*_*ror 7 qt qml

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

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

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

void KeyboardPlatformInputContext::setFocusObject(QObject* object)
{
    qDebug() << m_focusedObject << object;
    m_focusedObject = object;
}
Run Code Online (Sandbox Code Playgroud)

当按键被按下时,它们QEvents像这样传递

void KeyboardPlatformInputContext::processNormalKeyClick(const QString& key)
{
    qDebug() << m_focusedObject << key;
    if (m_focusedObject) {
        QInputMethodEvent inputEvent;
        inputEvent.setCommitString(key);
        QGuiApplication::sendEvent(m_focusedObject, &inputEvent);
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,利用可用的信息(m_focusedObject和QGuiApplication),可以做一些事情来保持输入字段的可见性。总是。

Mit*_*tch 6

库巴有正确的想法;我只会扩展它。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
    }
}
Run Code Online (Sandbox Code Playgroud)

要使其可用于虚拟键盘,请将内容移动到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
    }
}
Run Code Online (Sandbox Code Playgroud)

需要注意的几点:

anchors.bottomMargin: keyboardRect.visible ? keyboardRect.height : anchors.margins
Run Code Online (Sandbox Code Playgroud)

这确保了当键盘可见时内容被“推”起来,因此它下面没有隐藏任何东西。

onActiveFocusChanged: {
    if (activeFocus) {
        keyboardRect.visible = activeFocus

        var posWithinFlickable = mapToItem(column, 0, height / 2);
        flickable.contentY = posWithinFlickable.y - flickable.height / 2;
    }
}
Run Code Online (Sandbox Code Playgroud)

此代码不考虑失去焦点,因此键盘始终保持打开状态。

我们Flickable通过将字段的位置映射到 来关注当前输入字段Column。

最后,当您单击列顶部或底部附近的字段时,您会看到一些跳跃。这可能可以通过不设置contentY字段是否靠近顶部或底部来解决。供读者练习。:)