如何制作跟踪/控制任何布尔属性的QML切换按钮
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何制作跟踪/控制任何布尔属性的QML切换按钮相关的知识,希望对你有一定的参考价值。
我今天的QML / QtQuick练习是制作一个小ToggleButton小部件,我可以实例化它来监视指定的布尔QML属性的状态,并且当我点击ToggleButton时也切换该属性的状态。
到目前为止,我有我的ToggleButton组件:
// Contents of ToggleButton.qml
import QtQuick 2.2
import QtQuick.Controls 1.2
import QtQuick.Controls.Styles 1.4
Button {
property bool isActive: false
onClicked: {
isActive = !isActive;
}
style: ButtonStyle {
background: Rectangle {
border.width: control.activeFocus ? 2 : 1
border.color: "black"
radius: 4
color: isActive ? "red" : "gray";
}
}
}
....这是我的小测试工具,我用它来看它是否按照我想要的方式工作:
// Contents of main.qml
import QtQuick 2.6
import QtQuick.Window 2.2
Window {
visible: true
width: 360
height: 360
Rectangle {
property bool lighten: false;
id:blueRect
x: 32; y:32; width:64; height:64
color: lighten ? "lightBlue" : "blue";
MouseArea {
anchors.fill: parent
onClicked: parent.lighten = !parent.lighten;
}
}
Rectangle {
property bool lighten: false;
id:greenRect
x:192; y:32; width:64; height:64
color: lighten ? "lightGreen" : "green";
MouseArea {
anchors.fill: parent
onClicked: parent.lighten = !parent.lighten;
}
}
ToggleButton {
x:32; y:128
text: "Bright Blue Rect"
isActive: blueRect.lighten
}
ToggleButton {
x:192; y:128
text: "Bright Green Rect"
isActive: greenRect.lighten
}
}
你可以通过将代码保存到ToggleButton.qml和main.qml(分别)然后运行“qmlscene main.qml”来运行它。
请注意,如果单击蓝色或绿色矩形,它将按预期工作; Rectangle对象的布尔“lighten”属性打开和关闭,导致Rectangle改变颜色,相关的ToggleButton也会做出适当的反应(当“lighten”属性为true时自动变为红色,而当“lighten”变亮时为灰色“财产是假的”。
到目前为止,这么好,但如果你再单击ToggleButton本身,绑定就会被破坏:也就是说,点击ToggleButton会导致ToggleButton按预期变成红色/灰色,但是矩形的颜色不适合,在这之后,单击矩形不再导致ToggleButton的状态发生变化。
我的问题是,正确执行此操作的诀窍是什么,以便我始终在ToggleButton与其正在跟踪的属性之间存在双向对应关系? (请注意,理想的解决方案是尽可能少地为main.qml添加代码,因为我希望将此功能封装在ToggleButton.qml中,以最大限度地减少暴露给我的其他QML应用程序的复杂程度)
这不起作用的原因是您用固定值覆盖绑定。通过在onClicked
中手动分配值,可以用值覆盖绑定。
问题是:QML现在不支持双向绑定。但是,有一些技巧可以创建一个。见http://imaginativethinking.ca/bi-directional-data-binding-qt-quick/
注意:为什么不使用按钮的选中状态,而不是像这样使用isActive
属性? (来自documentation)这样即使单击按钮,绑定也不会中断:
// Contents of ToggleButton.qml
import QtQuick 2.2
import QtQuick.Controls 1.2
import QtQuick.Controls.Styles 1.4
Button {
//use the "checked" property instead of your own "isActive"
checkable: true
style: ButtonStyle {
background: Rectangle {
border.width: control.activeFocus ? 2 : 1
border.color: "black"
radius: 4
color: checked? "red" : "gray";
}
}
}
看起来解决这个问题的一种方法是让ToggleButton使用别名属性而不是常规属性来声明其状态。这样只有一个外部属性(因为ToggleButton的内部属性实际上只是外部属性的别名),因此不需要双向绑定。这是QML代码的更新版本,可以按预期工作:
ToggleButton.qml:
// Contents of ToggleButton.qml
import QtQuick 2.2
import QtQuick.Controls 1.2
import QtQuick.Controls.Styles 1.4
Button {
onClicked: {
isActive = !isActive;
}
style: ButtonStyle {
background: Rectangle {
border.width: control.activeFocus ? 2 : 1
border.color: "black"
radius: 4
color: isActive ? "red" : "gray";
}
}
}
main.qml:
// Contents of main.qml
import QtQuick 2.6
import QtQuick.Window 2.2
Window {
visible: true
width: 360
height: 360
Rectangle {
property bool lighten: false;
id:blueRect
x: 32; y:32; width:64; height:64
color: lighten ? "lightBlue" : "blue";
MouseArea {
anchors.fill: parent
onClicked: parent.lighten = !parent.lighten;
}
}
Rectangle {
property bool lighten: false;
id:greenRect
x:192; y:32; width:64; height:64
color: lighten ? "lightGreen" : "green";
MouseArea {
anchors.fill: parent
onClicked: parent.lighten = !parent.lighten;
}
}
ToggleButton {
x:32; y:128
text: "Bright Blue Rect"
property alias isActive: blueRect.lighten
}
ToggleButton {
x:192; y:128
text: "Bright Green Rect"
property alias isActive: greenRect.lighten
}
}
以上是关于如何制作跟踪/控制任何布尔属性的QML切换按钮的主要内容,如果未能解决你的问题,请参考以下文章
如何在QML(QT Creator)中使用发光脉动效果制作元素动画?