How can I implement focus changing state into reusable QML component when I clicked or selected another item outside component body to call any event (highlight text, show/hide rectangle and etc). There is code I trying to implement highlight line under CheckBox text when item have focus, and hide that when focus is lost. Please help me to understand more effective way to implement it. Here is the source of element:
BreezeQuickCheckbox.qml
import QtQuick 2.4
Item {
id: root
property BreezeQuickPalette palette: BreezeQuickPalette
property bool checked: false
property string caption: "Checkbox"
property int fontSize: 18
implicitHeight: 48
implicitWidth: bodyText.width + 48
Rectangle{
id: body
width: 32
height: 32
anchors {
verticalCenter: parent.verticalCenter
left: parent.left
leftMargin: 8
rightMargin: 8
}
radius: 2
border{
width: 1
color: palette.iconGrey
}
color: "transparent"
}
Rectangle{
id: check
opacity: 1
radius: 1
color: palette.focusColor
anchors {
verticalCenter: body.verticalCenter
}
anchors.fill: body
anchors.margins: 4
transform: Rotation {
id: checkRotation
origin.x: check.width/2
origin.y: check.height/2
axis {
x: 1
y: 1
z: 0
}
angle: 90
Behavior on angle {
NumberAnimation {
duration: 150
easing.type: Easing.InOutQuad
}
}
}
smooth: true
}
Text {
id: bodyText
anchors {
verticalCenter: parent.verticalCenter
left: body.right
}
color: palette.normalText
text: caption
anchors.leftMargin: 8
font.pointSize: fontSize
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
}
Rectangle {
id: highlightLine
anchors{
horizontalCenter: bodyText.horizontalCenter
top: bodyText.bottom
topMargin: -2
}
width: bodyText.width
height: 2
color: palette.focusColor
}
MouseArea{
id: bodyArea
anchors.fill: parent
hoverEnabled: true
onEntered: {
if (checked == false){
body.border.color = palette.focusColor
} else if (checked == true){
body.border.color = palette.lightPlasmaBlue
check.color = palette.lightPlasmaBlue
}
}
onExited: {
if (checked == false){
body.border.color = palette.iconGrey
}
if (checked == true){
body.border.color = palette.focusColor
check.color = palette.focusColor
}
}
onClicked: {
if (checked == false){
checked = true
body.border.color = palette.lightPlasmaBlue
checkRotation.angle = 0
} else if (checked == true){
checked = false
body.border.color = palette.focusColor
checkRotation.angle = 90
}
}
}
onCheckedChanged: {
if (checked == true){
body.border.color = palette.focusColor
if (bodyArea.containsMouse) {
check.color = palette.lightPlasmaBlue
checkRotation.angle = 0
} else if (!bodyArea.containsMouse){
check.color = palette.focusColor
checkRotation.angle = 0
}
} else if (checked == false){
body.border.color = palette.iconGrey
checkRotation.angle = 90
}
}
}
You can see this snippet where actual line is declared:
Rectangle {
id: highlightLine
anchors{
horizontalCenter: bodyText.horizontalCenter
top: bodyText.bottom
topMargin: -2
}
width: bodyText.width
height: 2
color: palette.focusColor
}
Here is the palette code, if you are interested in it - it's subset of components with it's own palette:
BreezeQuickPalette.qml
import QtQuick 2.4
QtObject {
id: palette
property string theme: "light"
readonly property color normalText: if (theme == "light"){
charcoalGrey
} else if (theme == "dark"){
cardboardGrey
}
readonly property color inactiveText: asphalt
readonly property color activeText: plasmaBlue
readonly property color linkText: seaBlue
readonly property color negativeText: iconRed
readonly property color neutralText: bewareOrange
readonly property color positiveText: deepGreen
readonly property color focusColor: plasmaBlue
readonly property color hoverColor: plasmaBlue
readonly property color normalBackground: if (theme == "light"){
cardboardGrey
} else if (theme == "dark"){
charcoalGrey
}
readonly property color alternateBackground: if (theme == "light"){
steel
} else if (theme == "dark"){
shadeBlack
}
readonly property color paperWhite: "#fcfcfc"
readonly property color cardboardGrey: "#eff0f1"
readonly property color iconGrey: "#4d4d4d"
readonly property color charcoalGrey: "#31363b"
readonly property color shadeBlack: "#232629"
readonly property color plasmaBlue: "#3daee9"
readonly property color iconRed: "#da4453"
readonly property color dangerRed: "#ed1515"
readonly property color iconOrange: "#f47750"
readonly property color bewareOrange: "#f67400"
readonly property color iconYellow: "#fdbc4b"
readonly property color sunbeamYellow: "#c9ce3b"
readonly property color mellowTurquoise: "#1cdc9a"
readonly property color iconGreen: "#2ecc71"
readonly property color verdantGreen: "#11d116"
readonly property color iconBlue: "#1d99f3"
readonly property color seaBlue: "#2980b9"
readonly property color skyBlue: "#3498db"
readonly property color turquoise: "#1abc9c"
readonly property color deepGreen: "#27ae60"
readonly property color deepTurquoise: "#16a085"
readonly property color peach: "#e74c3f"
readonly property color lightMaroon: "#c0392b"
readonly property color deepYellow: "#f39c1f"
readonly property color purple: "#9b59b6"
readonly property color deepPurple: "#8e44ad"
readonly property color steelBlue: "#34495e"
readonly property color charcoal: "#2c3e50"
readonly property color asphalt: "#7f8c8d"
readonly property color steel: "#bdc3c7"
readonly property color grey: "#95a5a6"
readonly property color lightPlasmaBlue: "#63beed"
}
Please help me to understand how can I make this Rectangle
visible or hidden once I clicked or selected something outside/inside of root item. This is what I'm trying to see when reusable CheckBox
is focused, and hide underline when focus gone and passed to another component or even clicked outside of element.
Bind
highlightLine.visible
toroot.activeFocus
so the highlight only shows when the checkbox gains active focus:The active focus can be set in many ways. For example, when user clicked the checkbox:
And you can write a simple program to verify the result:
For more information about focus, check Keyboard focus in Qt Quick.