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!
