A TextInput Component


In a previous post we post, we developed a beautiful TextInput with borders. In this post, we will extract this in a component for later reuse.

The previus developed TextInput scene looked like this:

import Qt 4.6

Item {
    width: 200
    height: 200

    Background { id: background }
    Item {
        property alias text: input.text
        anchors.centerIn: parent
        width: 180; height: 28
        BorderImage {
            source: "images/lineedit.sci"
            anchors.fill: parent
        }
        TextInput {
            id: input
            color: "#151515"; selectionColor: "green"
            font.pixelSize: 16; font.bold: true
            width: parent.width-16
            maximumLength: 16
            anchors.centerIn: parent
            focus: true
        }
    }
}

To be able to extract a text input component we create a new file called LineInput.qml. And extract the relevant parts.

import Qt 4.6

Item {
    property alias text: input.text
    property alias maximumLength: input.maximumLength
    anchors.centerIn: parent
    width: 180; height: 28
    BorderImage {
        source: "images/lineedit.sci"
        anchors.fill: parent
    }
    TextInput {
        id: input
        color: "#151515"; selectionColor: "green"
        font.pixelSize: 16; font.bold: true
        width: parent.width-16
        anchors.centerIn: parent
        focus: true
    }
}

I added an alias to the maximum length for convenience. The calling code changes now to:

LineInput {
    anchors.centerIn: parent
    width: 140
    text: "My LineEdit"
}

What happens now is the TextInput does not get focus for editing. My first attempt was to add just focus: true to the LineInput. But this didn’t solve the problem. Also the LineInput received the focus, its not forwarded to the inner text input.
My second attempt was to add an alias for focus on the LineInput to forward the focus. This resulted in a

Cannot override FINAL property ‘property alias focus: true’

message. What now?

FocusScope to the rescue.

A FocusScope defines a boundary for focus. If one child-element has set focus: true and the focus scope will receive focus it will forward the focus to that element.

You can read more about focus handling in QML here.

So we change our Item in LineInput.qml to a FocusScope:

import Qt 4.6

FocusScope {
    property alias text: input.text
    property alias maximumLength: input.maximumLength
    anchors.centerIn: parent
    width: 180; height: 28
    BorderImage {
        source: "images/lineedit.sci"
        anchors.fill: parent
    }
    TextInput {
        id: input
        color: "#151515"; selectionColor: "green"
        font.pixelSize: 16; font.bold: true
        width: parent.width-16
        anchors.centerIn: parent
        focus: true
    }
}

And the calling code to:

LineInput {
    anchors.centerIn: parent
    width: 140
    text: "My LineEdit"
    focus: true
}

The focus is now forwarded into the focus requesting element inside the scope. Sweet.

Exposing the TextInput

While I aliased some properties of the TextInput in the component for easier access it is also possible to expose the TextInput itself. Just use

property alias input: input

in LineInput.qml and now you can access the TextInput like this:

LineInput {
    anchors.centerIn: parent
    width: 140
    focus: true
    input.text: "No Way"
}

Another sweet thing 😉 Take care!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s