QtQuick2 - 当根项的 selecting/clicking outside/inside 时,QML 可重用项焦点发生变化
QtQuick2 - QML reusable item focus changes when selecting/clicking outside/inside of root item
当我单击或选择组件主体外部的另一个项目以调用任何事件(突出显示文本、show/hide 矩形等)时,如何将焦点更改状态实现为可重用的 QML 组件。当项目具有焦点时,我试图在 CheckBox 文本下实现高亮行,并在失去焦点时隐藏它。请帮助我了解更有效的实施方式。这是元素的来源:
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
}
}
}
您可以在声明实际行的地方看到这个片段:
Rectangle {
id: highlightLine
anchors{
horizontalCenter: bodyText.horizontalCenter
top: bodyText.bottom
topMargin: -2
}
width: bodyText.width
height: 2
color: palette.focusColor
}
这是调色板代码,如果您对它感兴趣 - 它是具有自己调色板的组件的子集:
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"
}
请帮助我了解如何在单击或选择根项目的 outside/inside 后使此 Rectangle
可见或隐藏。这就是我在可重用 CheckBox
聚焦时试图看到的内容,并在焦点消失并传递到另一个组件甚至在元素外部单击时隐藏下划线。
将 highlightLine.visible
绑定到 root.activeFocus
,这样只有当复选框获得活动焦点时才会突出显示:
Rectangle {
id: highlightLine
//...
visible: root.activeFocus
}
可以通过多种方式设置活动焦点。例如,当用户单击复选框时:
MouseArea{
id: bodyArea
onClicked: {
//...
root.forceActiveFocus(); //set root's active focus when mouse clicked
}
}
你可以编写一个简单的程序来验证结果:
Row {
BreezeQuickCheckbox {}
BreezeQuickCheckbox {}
BreezeQuickCheckbox {}
}
有关焦点的详细信息,请查看 Keyboard focus in Qt Quick。
当我单击或选择组件主体外部的另一个项目以调用任何事件(突出显示文本、show/hide 矩形等)时,如何将焦点更改状态实现为可重用的 QML 组件。当项目具有焦点时,我试图在 CheckBox 文本下实现高亮行,并在失去焦点时隐藏它。请帮助我了解更有效的实施方式。这是元素的来源:
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
}
}
}
您可以在声明实际行的地方看到这个片段:
Rectangle {
id: highlightLine
anchors{
horizontalCenter: bodyText.horizontalCenter
top: bodyText.bottom
topMargin: -2
}
width: bodyText.width
height: 2
color: palette.focusColor
}
这是调色板代码,如果您对它感兴趣 - 它是具有自己调色板的组件的子集:
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"
}
请帮助我了解如何在单击或选择根项目的 outside/inside 后使此 Rectangle
可见或隐藏。这就是我在可重用 CheckBox
聚焦时试图看到的内容,并在焦点消失并传递到另一个组件甚至在元素外部单击时隐藏下划线。
将 highlightLine.visible
绑定到 root.activeFocus
,这样只有当复选框获得活动焦点时才会突出显示:
Rectangle {
id: highlightLine
//...
visible: root.activeFocus
}
可以通过多种方式设置活动焦点。例如,当用户单击复选框时:
MouseArea{
id: bodyArea
onClicked: {
//...
root.forceActiveFocus(); //set root's active focus when mouse clicked
}
}
你可以编写一个简单的程序来验证结果:
Row {
BreezeQuickCheckbox {}
BreezeQuickCheckbox {}
BreezeQuickCheckbox {}
}
有关焦点的详细信息,请查看 Keyboard focus in Qt Quick。