信号及槽(signal-slot)是Qt语言最基本的,也是最有用的一个机制。这是它区分和其他一起语言的一个显据的标志。
我们先来下载我已经写好的应用:
bzr branch lp:~liu-xiao-guo/debiantrial/trafficlightwith3lights
使用Ubuntu SDK来打开我们已经创建好的应用。然后再打开文件“MyLight.qml”。在文件的开始部分加入如下的语句:
Item { <strong>id: root</strong> width: units.gu(100) height: units.gu(75) signal redLightOn signal greenLightOn signal yellowLightOn Rectangle { id: background anchors.fill: parent color: "black" property int size: width*0.7
接下来,我们在我们的JS代码中来发送这些信号。代码如下:
Timer { interval: 1000 running: true repeat: true property int count: 0 onTriggered: { if (parent.state == "red_on" && count >= 5) { parent.state = "red_yellow_on" <strong> root.redLightOn(); root.yellowLightOn();</strong> count = 0 } else if ( parent.state == "red_yellow_on" ) { parent.state = "green_on" <strong>root.greenLightOn();</strong> count++ } else if ( parent.state == "green_on" && count >= 5 ) { parent.state = "yellow_on" <strong> root.yellowLightOn();</strong> count ++ } else if ( parent.state == "yellow_on" ) { parent.state = "red_on" redLightOn(); count = 0 } else { count++ } } }
为了在我们的代码部分截取这个应用,我们可以使用如下的方法。在“TrafficLight.qml”中,修改代码为:
import QtQuick 2.0 import Ubuntu.Components 0.1 import "ui" MainView { // objectName for functional testing purposes (autopilot-qt5) objectName: "mainView" // Note! applicationName needs to match the "name" field of the click manifest applicationName: "com.ubuntu.developer.liu-xiao-guo.TrafficLight" /* This property enables the application to change orientation when the device is rotated. The default is false. */ //automaticOrientation: true width: units.gu(120) height: units.gu(80) Page { id:main anchors.fill: parent Row { id: myrow anchors.horizontalCenter: parent.horizontalCenter anchors.verticalCenter: parent.verticalCenter spacing: units.gu(5) MyLight { id:light width: main.width/5 height: width*3 onRedLightOn: { console.log("red light is on") } } Connections { target: light onYellowLightOn: { console.log("yellow light is on") } } } function greenLightOn() { console.log("green light is on") } Component.onCompleted: { light.greenLightOn.connect(greenLightOn); } } }
为了说明清楚,我写了三种方法。一种是直接把信号的第一个字母变为大写, 并同时在前面加上"on“。第二种方法使用”Connections"来实现槽的连接。第三种方法,我们可以直接 把信号连接到一个JS的函数上。运行程序,我们可以在应用的输出窗口看到如下的输出:
green light is on yellow light is on red light is on red light is on yellow light is on green light is on yellow light is on red light is on red light is on yellow light is on
事实上所有的控件的property都可以发出一个信号。让我们来看一下我们先前完成的“color” property。
void TrafficLight::setColor(const QColor &color) { if ( color == m_color ) return; else { m_color = color; update(); // repaint with the new color emit colorChanged(); } }
TrafficLight{ id: redlight width: background.size height: background.size color:"red" onColorChanged: { console.log("Color is changed to " + color); } }
TrafficLight{ id: redlight width: background.size height: background.size color:"red" onColorChanged: { console.log("Color is changed to " + color); } onWidthChanged: { console.log("width is changed to " + width); } }
更多阅读可以在连接找到http://qt-project.org/doc/qt-4.8/qmlevents.html。