Chapter 2: Connecting to C++ Methods and Signals (章节二:连接C++方法和信号)
extending-qml/chapter2-methods
假设我们想使PieChart 拥有“clearChart()”方法去删除图表,并激活chartCleared信号。我们的app.qml将能够调用clearChart()并接收chartCleared()信号,如下所示:
import Charts 1.0
import QtQuick 2.0
Item {
width: 300; height: 200
PieChart {
id: aPieChart
anchors.centerIn: parent
width: 100; height: 100
color: "red"
onChartCleared: console.log("The chart has been cleared")
}
MouseArea {
anchors.fill: parent
onClicked: aPieChart.clearChart()
}
Text {
anchors { bottom: parent.bottom; horizontalCenter: parent.horizontalCenter; bottomMargin: 20 }
text: "Click anywhere to clear the chart"
}
}
为此,我们向C++类添加了clearChart()方法和chartCleared()信号:
class PieChart : public QQuickPaintedItem
{
...
public:
...
Q_INVOKABLE void clearChart();
signals:
void chartCleared();
...
};
Q_invokable的使用使得clearChart()方法可用于Qt元对象系统,进而也可用于QML。请注意,它也可以声明为Qt槽,而不是使用Q_Invookable,因为槽也可以从QML调用。这两种方法都是有效的。
ClearChart()方法只需将颜色更改为qt::transparent,重新绘制图表,然后发出chartCleared()信号:
void PieChart::clearChart()
{
setColor(QColor(Qt::transparent));
update();
emit chartCleared();
}
现在,当我们运行应用程序并单击窗口时,饼图消失,应用程序输出:
qml: The chart has been cleared
Chapter 3: Adding Property Bindings (第3章:添加属性绑定)
extending-qml/chapter3-bindings
属性绑定是QML的一个强大功能,它允许自动同步不同类型的值。当属性值更改时,它使用信号通知和更新其他类型的值。
让我们为color属性启用属性绑定。代码如下:
import Charts 1.0
import QtQuick 2.0
Item {
width: 300; height: 200
Row {
anchors.centerIn: parent
spacing: 20
PieChart {
id: chartA
width: 100; height: 100
color: "red"
}
PieChart {
id: chartB
width: 100; height: 100
color: chartA.color
}
}
MouseArea {
anchors.fill: parent
onClicked: { chartA.color = "blue" }
}
Text {
anchors { bottom: parent.bottom; horizontalCenter: parent.horizontalCenter; bottomMargin: 20 }
text: "Click anywhere to change the chart color"
}
}
“color:chartA.color”语句将chartB的颜色值绑定到charta的颜色。每当Charta的颜色值更改时,ChartB的颜色值都会更新为相同的值。单击窗口时,MouseArea中的onClicked处理程序会更改Charta的颜色,从而将两个图表都更改为蓝色。
为颜色属性启用属性绑定很容易。我们在其q_property()声明中添加了通知功能,以指示只要值发生更改,就会发出“ColorChanged”信号。
class PieChart : public QQuickPaintedItem
{
...
Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
public:
...
signals:
void colorChanged();
...
};
然后,我们在setPieSlice()中发出此信号:
void PieChart::setColor(const QColor &color)
{
if (color != m_color) {
m_color = color;
update(); // repaint with the new color
emit colorChanged();
}
}
SetColor()在发出ColorChanged()之前检查颜色值是否已实际更改,这一点很重要。这可以确保信号不会不必要地发出,还可以防止在其他类型响应值更改时出现循环。
绑定的使用对QML至关重要。如果属性能够实现,则应始终为其添加通知信号,以便可以在绑定中使用您的属性。无法绑定的属性不能自动更新,也不能在QML中灵活使用。此外,由于绑定在QML使用中被频繁调用和依赖,如果没有实现绑定,您的自定义QML类型的用户可能会看到意外的行为。