QML TextField and overlay keyboard



  • Hi devs, I`m currently develope a mobile cross-platform app (Qt 5.9.1) which has a contact page.
    This page has many textfields (e.g name, lastname, street, city .....) and on the bottom a send-button. When I input some text in the fields, the overlay keyboard becomes visible and covers my send-button. It is possible to move the page top, when the overlay keyboard becomes visible (e.g WhatsApp has this feature).

    Example code:

    import QtQuick 2.7
    import QtQuick.Controls 2.2
    import QtQuick.Layouts 1.3
    import QtGraphicalEffects 1.0
    import QtQuick.Controls.Material 2.2
    
    ApplicationWindow {
        visible: true
        width: 640
        height: 480
        title: qsTr("Example")
    
        Flickable {
            id: flickable
            contentHeight: root.implicitHeight
            anchors.fill: parent
            boundsBehavior: Flickable.OvershootBounds
            clip: true
    
            Pane {
                id: root
                anchors.fill: parent
                padding: 0
                ColumnLayout {
                    id: theContent
                    anchors.right: parent.right
                    anchors.left: parent.left
    
                    RowLayout {
                        Label {
                            topPadding: 6
                            leftPadding: 6
                            font.pointSize: 20
                            text: qsTr("Contact")
                            Layout.fillWidth: true
                        }
                    }
    
                    RowLayout {
                        Layout.leftMargin: 20
                        Layout.rightMargin: 20
                        Label {
                            wrapMode: Text.WordWrap
                            text: qsTr("First name: ")
                            Layout.fillWidth: true
                            Layout.preferredWidth: 2
                        }
                        TextField {
                            id: textFieldFirstName
                            Layout.fillWidth: true
                            Layout.preferredWidth: 3
                            onEditingFinished: {
                                focus = false
                            }
                        } // textField
    
                    } // row
    
                    RowLayout {
                        Layout.leftMargin: 20
                        Layout.rightMargin: 20
                        Label {
                            wrapMode: Text.WordWrap
                            text: qsTr("Last name: ")
                            Layout.fillWidth: true
                            Layout.preferredWidth: 2
                        }
                        TextField {
                            id: textFieldLastName
                            Layout.fillWidth: true
                            Layout.preferredWidth: 3
                            onEditingFinished: {
                                focus = false
                            }
                        } // textField
    
                    } // row
    
                    RowLayout {
                        Layout.leftMargin: 20
                        Layout.rightMargin: 20
                        Label {
                            wrapMode: Text.WordWrap
                            text: qsTr("Company: ")
                            Layout.fillWidth: true
                            Layout.preferredWidth: 2
                        }
                        TextField {
                            id: textFieldCompany
                            Layout.fillWidth: true
                            Layout.preferredWidth: 3
                            onEditingFinished: {
                                focus = false
                            }
                        } // textField
    
                    } // row
    
                    RowLayout {
                        Layout.leftMargin: 20
                        Layout.rightMargin: 20
                        Label {
                            wrapMode: Text.WordWrap
                            text: qsTr("City: ")
                            Layout.fillWidth: true
                            Layout.preferredWidth: 2
                        }
                        TextField {
                            id: textFieldCity
                            Layout.fillWidth: true
                            Layout.preferredWidth: 3
                            onEditingFinished: {
                                focus = false
                            }
                        } // textField
    
                    } // row
    
                    RowLayout {
                        Layout.leftMargin: 20
                        Layout.rightMargin: 20
                        Label {
                            wrapMode: Text.WordWrap
                            text: qsTr("E-mail: ")
                            Layout.fillWidth: true
                            Layout.preferredWidth: 2
                        }
    
                        TextField {
                            id: textFieldEMail
                            Layout.fillWidth: true
                            Layout.preferredWidth: 3
                            onEditingFinished: {
                                focus = false
                            }
                        } // textField
    
                    } // row
    
                    RowLayout {
                        Layout.leftMargin: 20
                        Layout.rightMargin: 20
                        Layout.topMargin: 6
                        Label {
                            wrapMode: Text.WordWrap
                            text: qsTr("Your message: ")
                            Layout.fillWidth: true
                            Layout.preferredWidth: 3
                        }
                    } // row
                    Rectangle {
                        Layout.leftMargin: 20
                        Layout.rightMargin: 20
                        Layout.fillWidth: true
                        height: 200
                        color: "white"
                        border.width: 1
                        border.color: "darkgrey"
                        ScrollView {
                            id: view
                            anchors.fill: parent
                            width: parent.width
                            anchors.margins: 6
                            TextArea {
                                id: textAreaMessage
                                implicitWidth: parent.width
                                selectByMouse: true
                                hoverEnabled: false
                                wrapMode: TextEdit.WordWrap
                                onEditingFinished: {
                                    focus = false
                                }
                            } // textArea
                        }
                    }
    
                    Button {
                        id: buttonSend
                        enabled: textFieldFirstName.text.length != 0 && textFieldLastName.text.length != 0
                        text: "Send"
                        anchors.right: parent.right
                        anchors.rightMargin: 20
                        onClicked: {
                            console.log("Send-Button clicked")
                        }
                    }
    
                } // col layout
            } // root
            ScrollIndicator.vertical: ScrollIndicator { }
        } // flickable
    }
    
    

  • Moderators

    You can get keyboardRectangle() from Qt.inputMethod and use that information to scroll your view.



  • @sierdzio Thank you for your fast answer. Have you a little example for me how I can use this?


  • Moderators

    I don't, unfortunately.

    Some hackish solution is available here and here.



  • @sierdzio Thank you, this helps a lot



  • Does anyone know how to move the flickable to a specific height. I`ve tested a bit with flickable.flick, but this seems not the proper way


  • Moderators

    Try setting contentX or contentY properties.



  • @sierdzio Whith which function should i test it? Flickable does not have a function to move it programmaticaly besides flick( )


  • Moderators

    @Manu19 said in QML TextField and overlay keyboard:

    @sierdzio Whith which function should i test it? Flickable does not have a function to move it programmaticaly besides flick( )

    contenxtX is a property. Just set it's value to any value you need and it will update the position automatically.

    For example:

    Button {
      onClicked: flickable.contentY += 100
    }
    
    Flicakble {
      id: flickable
      // some contents
    }
    

    Or:

    Flickable {
      id: flickable
      contentY: keyboardRect.height
    }
    
    Rectangle {
      id: keyboardRect
      height: keyboardVisible? 500 : 0
    }
    


  • @sierdzio Shame on me. I thought contentY would be readOnly. I should go to bed and sleep. Thank you for your patience and for your example


  • Moderators

    @Manu19 said in QML TextField and overlay keyboard:

    @sierdzio Shame on me. I thought contentY would be readOnly. I should go to bed and sleep. Thank you for your patience and for your example

    Hehe, no worries. This property actually sounds almost as if it should be read-only. Before I wrote my reply I checked several times if it was writable or not, because I felt intuitively that it could not be :-) So, I understand you 100% here :D


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.