前面兩篇文章《QML 語言基礎》和《Qt Quick 簡單教程》中我們介紹了 QML 語言的基本語法和 Qt Quick 的常見元素,親們,通過這兩篇文章,您應該已經可以完成簡單的 Qt Quick 應用了。接下來呢,哈,我們要介紹 Qt Quick 中一個灰常灰常重要的主題:事件處理。這將是比較長長長長的一篇,哦,不還有后續好幾篇……廢話少說,還是談正事兒吧兄弟姐妹們。
本文是作者 Qt Quick 系列文章中的一篇,其它文章在這里:
- Qt Quick 簡介
- QML 語言基礎
- Qt Quick 之 Hello World 圖文詳解
- Qt Quick 簡單教程
- Qt Quick 事件處理之信號與槽
- Qt Quick事件處理之鼠標、鍵盤、定時器
- Qt Quick 事件處理之捏拉縮放與旋轉
- Qt Quick 組件與對象動態創建詳解
- Qt Quick 布局介紹
- Qt Quick 之 QML 與 C++ 混合編程詳解
GUI 應用都是基於事件的(同學,這么說對嗎?),不管是用 C++ 還是用 QML ,你的應用都要處理事件,否則的話,哼哼,要你好看!當然當然,你也可以什么事兒不干,就搭個靜態界面放那里欣賞……
Qt Quick 最大的一個特點,是與 Qt 元對象系統的結合;而這里邊,我們熟稔的,鼎鼎大名大名鼎鼎的,要不斷打交道的,就是信號與槽了。歷史是割不斷的,繼承與發展才是正確的價值觀……,了解過 Qt 的開發者一定對信號與槽印象深刻。在 QML 中,在 Qt Quick 中,要想妥善的處理各種事件,同樣離不開信號與槽。所以呢,在介紹具體的事件之前,我們先要介紹 QML 中如何使用信號與槽。
為了演示本文的示例,我們先介紹一個工具: qmlscene 。
qmlscene 工具
這是 Qt 框架提供的便利工具,使用它,你可以不用建立項目不用撰寫 C++ 代碼,就可以看到你編寫的 qml 文件的效果。我們以 Windows 7 系統為例, qmlscene 需要在命令行窗口中使用。你可以這樣打開 Qt 自帶的命令行開發環境,參考圖 1 找到命令行環境的快捷方式:
圖 1 Qt 命令行環境的快捷方式
一旦你打開了命令行工具,它會幫你設置好 Qt 需要的環境變量,敲一個 qmake 命令試試吧。如和 圖 2 所示:
圖 2 Qt 命令行開發環境
如果你想知道 qmlscene 工具的詳細用法,請輸入 qmlscene --help 命令。如圖 3 :
圖 3 qmlscene 的幫助
現在,使用 cd 命令切換到你存放 qml 文檔的目錄下,就可以驗證 qml 的效果了。只需要執行這樣的命令: qmlscene yourapp.qml 。當然,yourapp.qml 要替換為你實際的 qml 文檔的名字。我這里只是示例。如果你直接輸入 qmlscene 命令來執行,那么它會打開一個文件選擇對話框,讓你選擇一個 qml 文檔,當你選擇了之后呢,該文檔對應的界面就會顯示出來。我建議你使用 qmlscene yourapp.qml 這種方式,無它,唯快爾。
來看一個簡單的 Hello World ,qml 文檔是 hello_world.qml ,內容如下:
- import QtQuick 2.0
- import QtQuick.Controls 1.1
- Rectangle {
- width: 320;
- height: 240;
- color: "gray";
- Text {
- anchors.centerIn: parent;
- text: "Hello World!";
- color: "blue";
- font.pixelSize: 32;
- }
- }
在命令行環境執行 qmlscene hello_world.qml ,效果如圖 4 所示:
圖 4 使用 qmlscene 執行 Hello World 示例
好啦, qmlscene 的介紹到此為止,下面我們來看信號與槽了。
連接 QML 類型的已知信號
我們先看一個簡單的示例, qml 中只有一個退出按鈕,點擊退出應用。 qml 文檔為 button_quit.qml ,內容如下:
- import QtQuick 2.0
- import QtQuick.Controls 1.1
- Rectangle {
- width: 320;
- height: 240;
- color: "gray";
- Button {
- text: "Quit";
- anchors.centerIn: parent;
- onClicked: {
- Qt.quit();
- }
- }
- }
使用 qmlscene 執行 button_quit.qml 效果如圖 5 所示:
圖 5 button_quit 示例效果
現在看看代碼有何特別之處。其實在《Qt on Android: Qt Quick 簡單教程》中我們已經見過類似的代碼了:
- onClicked:{}
對,就是這個 onClicked ,其實就包含了 QML 中使用信號與槽的一般形式:信號處理器。
信號處理器
信號處理器,其實等價於 Qt 中的槽。但是我們沒有看到類似 C++ 中的明確定義的函數……沒錯,就是這樣,你的的確確只看到了一對花括號!對啦,這是 JavaScript 中的代碼塊。其實呢,你可以理解為它是一個匿名函數。而 JavaScript 中的函數,其實具名的代碼塊。函數的好處是你可以在其它地方根據名字調用它,而代碼塊的好處是,除了定義它的地方,沒人能調用它,一句話,它是私有的。代碼塊就是一系列語句的組合,它的作用就是使語句序列一起執行。
讓我們回頭再看信號處理器,它的名字還有點兒特別,一般是 on{Signal} 這種形式。在上節的示例中, Button 元素有一個名為 clicked() 的信號,我們提供的信號處理器是醬紫的:
- onClicked: {
- Qt.quit();
- }
非常簡單吧,僅僅是調用 Qt.quit() 來退出應用而已。
Qt 對象是 Qt Quick 導出到 QML 環境中的對象,它的 quit() 方法退出應用。還有很多其它的方法,比如 rgba() 用於構造一個顏色(color類型), md5() 用來計算一段數據的 MD5 值……
你看到了,當信號是 clicked() 時,信號處理器就命名為 onClicked 。就這么簡單,以 on 起始后跟信號名字(第一個字母大寫)。如果你點擊我們的 quit 按鈕,應用就真的退出了。
上面的示例,信號處理器放在擁有信號的元素內部,當元素信號發射時處理器被調用。還有一種情況,要處理的信號不是當前元素發出來的,而是來自其它類型(對象)比如處理按鍵的 Keys ,這就是附加信號處理器。
附加信號處理器
在 QML 語言的語法中,有一個附加屬性(attached properties)和附加信號處理器(attached signal handlers)的概念,這是附加到一個對象上的額外的屬性。從本質上講,這些屬性是由附加類型(attaching type)來實現和提供的,它們可能被附加到另一種類型的對象上。附加屬性與普通屬性的區別在於,對象的普通屬性是由對象本身或其基類(或沿繼承層級向上追溯的祖先們)提供的。
舉個例子,下面的 Item 對象使用了附加屬性和附加信號處理器:
- import QtQuick 2.0
- Item {
- width: 100;
- height: 100;
- focus: true;
- Keys.enabled: false;
- Keys.onReturnPressed: console.log("Return key was pressed");
- }
你看, Item 對象可以訪問和設置 Keys.enabled 和 Keys.onReturnPressed 的值。
enabled 是 Keys 對象的一個屬性。
onReturnPressed 其實是 Keys 對象的一個信號。
對於附加信號處理器,和前面講到的普通信號處理器又有所不同。普通信號處理器,你先要知道信號名字,然后按照 on{Signal} 的語法來定義信號處理器的名字;而附加信號處理器,信號名字本身已經是 onXXX 的形式,你只要通過附加類型名字引用它,把代碼塊賦值給它即可。下面是另外的代碼片段:
- Rectangle {
- width: 320;
- height: 480;
- color: "gray";
- focus: true;
- Keys.enabled: true;
- Keys.onEscapePressed: {
- Qt.quit();
- }
- }
這個代碼片段實現的功能非常簡單:用戶按下 Esc 鍵時退出應用。
Component 對象也有一些附加信號,如 Component.onCompleted() 、 Component.onDestruction() 。可以用來在 Component 創建完成或銷毀時執行一些 JavaScript 代碼來做與初始化或反初始化相關的工作。比如下面的代碼:
- Rectangle {
- Component.onCompleted: console.log("Completed Running!");
- Component.onDestruction: console.log("Destruction Beginning!");
- }
信號處理器與附加信號處理器有一個共性:響應信號的代碼都放在元素內部,通過 JavaScript 代碼塊就地實現。而其實呢, Qt Quick 中還有另外一種方式來處理信號與槽,那就是:專業的 Connections 。
Connections
一個 Connections 對象創建一個到 QML 信號的連接。
前面兩節在處理 QML 信號時,都是用 on{Signal} 這種就地代碼塊的方式。而在有些情況下,這樣的處理並不方便。比如:
- 你需要將多個對象連接到同一個 QML 信號上
- 你需要在發出信號的對象的作用域之外來建立連接
- 發射信號的對象沒有在 QML 中定義(可能是通過 C++ 導出的,這很常見)
Connections 有一個屬性名為 target ,它呢,指向發出信號的對象。
下面就看看 Connections 怎么使用。一般的用法:
- Connections {
- target: area;
- on{Signal}: function or code block;
- }
來看一個實際的示例,是醬紫的:界面上放置兩個文本,一個按鈕,每點按鈕一次,兩個文本對象都變顏色,而它們的顏色隨機的。下面是示例代碼:
- import QtQuick 2.0
- import QtQuick.Controls 1.1
- Rectangle {
- width: 320;
- height: 240;
- color: "gray";
- Text {
- id: text1;
- anchors.horizontalCenter: parent.horizontalCenter;
- anchors.top: parent.top;
- anchors.topMargin: 20;
- text: "Text One";
- color: "blue";
- font.pixelSize: 28;
- }
- Text {
- id: text2;
- anchors.horizontalCenter: parent.horizontalCenter;
- anchors.top: text1.bottom;
- anchors.topMargin: 8;
- text: "Text Two";
- color: "blue";
- font.pixelSize: 28;
- }
- Button {
- id: changeButton;
- anchors.top: text2.bottom;
- anchors.topMargin: 8;
- anchors.horizontalCenter: parent.horizontalCenter;
- text: "Change";
- }
- Connections {
- target: changeButton;
- onClicked: {
- text1.color = Qt.rgba(Math.random(), Math.random(), Math.random(), 1);
- text2.color = Qt.rgba(Math.random(), Math.random(), Math.random(), 1);
- }
- }
- }
代碼比較簡單,除了 Connections 和 Math ,沒有其它的新內容,都是 《Qt Quick 簡單教程》和《QML 語言基礎》中講過的。我在 Connections 對象中指定 target 為 changeButton (Change按鈕的 id),然后定義了 onClicked 信號處理器,在信號處理器中使用 Math 對象的 random() 方法構造顏色值來改變兩個文本的顏色。
Math 是 JavaScript 語言內置的對象,有 random() / sin() / max() / min() / abs() 等等方法,參見 w3c 的文檔。
圖 6 是運行后的效果圖:
圖 6 Connections 的使用
到現在為止,我們說的都是如何使用 QML 中已有類型定義的信號。這些信號呢,其實又分類兩類。一類是由用戶輸入產生的,比如按鍵、鼠標、觸摸屏、傳感器等,另一類呢是由對象狀態或屬性變化產生的,比如 Image 對象的 status 屬性(在《Qt Quick 簡單教程》有用到)。那么有一個問題,就是,怎樣知道一個對象有哪些信號?
如何尋找感興趣的信號
怎樣找到你感興趣的信號呢?
Qt 幫助
首先是查閱 Qt 幫助,你可以使用 Qt 幫助的索引模式,以你關心的對象名字為關鍵字檢索,比如 Button ,檢索結果如圖 7 所示:
圖7 使用 Qt 幫助索引模式檢索 Button 對象
有時你會在查找結果中看到多個連接,點進去看看是否是 QML 類型即可。
還有另外一種方式,使用 Qt 幫助的目錄模式。如圖 8 所示:
圖 8 使用 Qt 幫助目錄模式
一旦你找到一個對象的文檔,你可以找到它的部分信號說明。還是以 Button 為例,看圖 9:
圖 9 Button 的信號 clicked()
Qt Quick 相關類型的文檔中,你可以看到對象的屬性和信號。列為屬性的,可以在 QML 中訪問;列為信號的,可以連接它,通過信號處理器來響應用於操作。
至於具體某個屬性或信號是何含義,點擊它們,跟過去看看吧。
話說,Qt 的文檔是否列出了 Qt Quick 類型的所有信號了呢?想必我這么說你用腳趾頭也可以想到答案:沒有!個人認為這是 Qt 5.2 文檔關於 Qt Quick 和 QML 類型手冊的一個缺失。前面提到 QML 中的信號,一類是輸入事件觸發的,一類是屬性變化觸發的。文檔中缺失的,正是屬性變化觸發的那些信號。不過呢,不過我們有辦法找到它。
從 Qt Quick 頭文件查看屬性相關的信號
要說呢, Qt Quick 中你看到的很多對象,都是 Qt C++ 中實現,然后導入到 QML 環境中的。所以呢,如果你關心那些被文檔隱藏了的信號,可以這么做:
- 找到 QML 類型對應的 C++ 類型
- 找到 C++ 類型的頭文件,查看屬性聲明來確認是否有信號與屬性關聯
怎么找 QML 類型對應的 C++ 類型呢?很簡單,只需要使用 Component.onCompleted 附加信號,在附加信號處理器中輸出類型信息即可。示例代碼:
- import QtQuick 2.0
- import QtQuick.Controls 1.1
- Rectangle {
- width: 320;
- height: 240;
- color: "gray";
- Text {
- id: text1;
- anchors.centerIn: parent;
- text: "Hello World!";
- color: "blue";
- font.pixelSize: 32;
- }
- Button {
- id: button1;
- text: "A Button";
- anchors.top: text1.bottom;
- anchors.topMargin: 4;
- }
- Image {
- id: image1;
- }
- Component.onCompleted: {
- console.log("QML Text\'s C++ type - ", text1);
- console.log("QML Button\'s C++ type - ", button1);
- console.log("QML Image\'s C++ type - ", image1);
- }
- }
如代碼所示,我們使用 console 對象來輸出 QML 對象,它會打印出 QML 對象的實際類型。圖 10 是使用 qmlscene 運行 cplusplus_types.qml 的效果圖:
圖 10 打印 QML 類型對應的 C++ 類型
別看界面效果哦,注意看命令行窗口的輸出。對,QML Text 對應的 C++ 類型是 QQuickText , QML Image 對應的 C++ 類型是 QQuickImage ,而 Button ,其實是 QML 中定義的對象(含有 QMLTYPE 字樣)。我這里使用的 Qt 5.2.0 ,如果是其他的 Qt 版本,比如 Qt 4.7 / Qt 4.8 ,能不能看到我就不知道了。
下面我們就以 QQuickText 為例,找到它的頭文件,路徑是 C:\Qt\Qt5.2.0\5.2.0\mingw48_32\include\QtQuick\5.2.0\QtQuick\private\qquicktext_p.h 。你的環境中根據 Qt SDK 安裝目錄,路徑可能有所不同。
看看 QQuickText 類的聲明吧(我截取了屬性部分的幾行代碼):
- // qquicktext_p.h
- //
- class Q_QUICK_PRIVATE_EXPORT QQuickText : public QQuickImplicitSizeItem
- {
- Q_OBJECT
- Q_ENUMS(HAlignment)
- Q_ENUMS(VAlignment)
- Q_ENUMS(TextStyle)
- Q_ENUMS(TextFormat)
- Q_ENUMS(TextElideMode)
- Q_ENUMS(WrapMode)
- Q_ENUMS(LineHeightMode)
- Q_ENUMS(FontSizeMode)
- Q_ENUMS(RenderType)
- Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
- Q_PROPERTY(QFont font READ font WRITE setFont NOTIFY fontChanged)
- Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
- Q_PROPERTY(QColor linkColor READ linkColor WRITE setLinkColor NOTIFY linkColorChanged)
- Q_PROPERTY(TextStyle style READ style WRITE setStyle NOTIFY styleChanged)
- ...
- }
親愛的,看到了嗎,那么多的 Q_PROPERTY 宏啊。 Q_PROPERTY 宏就是用來定義 QML 中可訪問屬性的,當你看到 NOTIFY 字樣,它后面的字段就是與屬性綁定的信號的名字。 Qt 實現了動態屬性綁定,當你為 QML Text 的屬性 color 賦值時,實際上會調用到 QQuickText 的 setColor() 函數,也會觸發 colorChanged() 信號。
再來看看 text 和 color 對應的信號原型:
- class Q_QUICK_PRIVATE_EXPORT QQuickText : public QQuickImplicitSizeItem
- {
- Q_OBJECT
- ...
- Q_SIGNALS:
- void textChanged(const QString &text);
- void colorChanged();
- }
看到了吧, textChanged 信號有個 text 參數。我們來看看 textChanged 信號怎樣在 QML 中使用。示例代碼(property_signal.qml):
- import QtQuick 2.0
- import QtQuick.Controls 1.1
- Rectangle {
- width: 320;
- height: 240;
- color: "gray";
- Text {
- id: hello;
- anchors.centerIn: parent;
- text: "Hello World!";
- color: "blue";
- font.pixelSize: 32;
- onTextChanged: {
- console.log(text);
- }
- }
- Button {
- anchors.top: hello.bottom;
- anchors.topMargin: 8;
- anchors.horizontalCenter: parent.horizontalCenter;
- text: "Change";
- onClicked: {
- hello.text = "Hello Qt Quick";
- }
- }
- }
當用戶點擊按鈕時,改變 Text 對象的文本為 "Hello Qt Quick" 。而我在 Text 對象中實現了 onTextChanged 信號處理器,使用 console.log 輸出新的文本。
注意啦,QML 信號的參數名字,可以直接在信號處理器中訪問。之前只用沒說,這里特意說一下這點。如果你通過頭文件找屬性綁定的信號,就可以觀察信號的參數,在 QML 中使用。
圖 11 是運行效果:
圖 11 屬性綁定的信號
你看,圖片上的文字變了哈,命令行也輸出了新的文本:"Hello Qt Quick" 。喏,沒騙你。
行文至此,如何在 QML 中使用已知類型的信號,已經介紹差不多了。
定義自己的信號
當自定義類型不可避免,當你需要通知別的對象你的狀態發生了變化,當你對象的粉絲想了解你對象的近況……此時此刻,彼時彼刻,最好的方法, Qt 給我們的,QML 給我們的,還是信號。
現在我們就來看怎么定義自己的信號。
自定義信號與使用
如果你自己定義新的 QML 類型,可以使用 signal 關鍵字給你的類型添加信號。其語法如下:
- signal <name>[([<type> <parameter name>[, ...]])]
這是你的類型通告自己狀態的最好的方式,符合 Qt 的風格,作為使用 Qt 的開發人員,還是崇德向善吧。
信號其實是個方法(函數),所以呢,它的發射,實際是通過調用以信號名為名的方法達成的。
舉個實例的例子:我們在界面上放一個字符串,兩個代表顏色的小方塊,點小方塊,字符串的顏色就變成小方塊的顏色。先看代碼(my_signal.qml):
- import QtQuick 2.0
- import QtQuick.Controls 1.1
- Rectangle {
- width: 320;
- height: 240;
- color: "#C0C0C0";
- Text {
- id: coloredText;
- anchors.horizontalCenter: parent.horizontalCenter;
- anchors.top: parent.top;
- anchors.topMargin: 4;
- text: "Hello World!";
- font.pixelSize: 32;
- }
- Component {
- id: colorComponent;
- Rectangle {
- id: colorPicker;
- width: 50;
- height: 30;
- signal colorPicked(color clr);
- MouseArea {
- anchors.fill: parent
- onPressed: colorPicker.colorPicked(colorPicker.color);
- }
- }
- }
- Loader{
- id: redLoader;
- anchors.left: parent.left;
- anchors.leftMargin: 4;
- anchors.bottom: parent.bottom;
- anchors.bottomMargin: 4;
- sourceComponent: colorComponent;
- onLoaded:{
- item.color = "red";
- }
- }
- Loader{
- id: blueLoader;
- anchors.left: redLoader.right;
- anchors.leftMargin: 4;
- anchors.bottom: parent.bottom;
- anchors.bottomMargin: 4;
- sourceComponent: colorComponent;
- onLoaded:{
- item.color = "blue";
- }
- }
- Connections {
- target: redLoader.item;
- onColorPicked:{
- coloredText.color = clr;
- }
- }
- Connections {
- target: blueLoader.item;
- onColorPicked:{
- coloredText.color = clr;
- }
- }
- }
這次代碼稍微有點長了。現在我來充當導游,請跟緊我哦,別擔心,不會強制你們買東西的。
首先定義了一個 Text 對象,id 為 coloredText ,后面會根據這個 id 來改變它的顏色。
然后我定義了一個組件,組件內有一個 Rectangle 對象,這里是我們定義信號的地方。我設置 Rectangle 的尺寸,然后定義了信號 colorPicked ,語句如下:
- signal colorPicked(color clr);
為了觸發信號,我給 Rectangle 引入了 MouseArea 。MouseArea 是專門處理鼠標操作的 item ,這里我們先知道它有一個 onClicked() 信號就行了。我們給這個信號指定信號處理器,在信號處理器中調用我們剛定義的信號:colorPicker.colorPicked(colorPicker.color); ……如你所見,信號的觸發就是一個函數調用。
組件是可以重復利用的,一個組件可以在一個單獨的 qml 文件中定義,也可以嵌入到其它 qml 文檔中來定義以方便簡單組件的使用。這里我選擇在主 qml 文檔內嵌入組件的定義。定義好了組件,就可以使用 Loader 來加載組件了。
Loader 是專門用來動態創建組件的,它可以從 qml 文件中創建組件,也可以指定 sourceComponent 來創建,這里的示例,因為組件是嵌入在主 qml 文件中定義的,所以使用了 sourceComponent 方式。我給每個 Loader 一個 id ,以便后面連接時使用。我還使用 anchors 為 Loader 布局。最后呢,在 Loader 的 onLoaded 信號處理器內給 Rectangle 對象配置顏色。
創建完 Loader ,就是建立連接了。這里使用 Connections 來建立信號的連接,target 指向剛才說的 Loader 對象的 item 屬性, item 屬性實際指向 Loader 創建的對象。在 Connections 對象中,通過 onColorPicked 信號處理器響應用戶點擊操作。你看到了,我們定義 colorPicked 信號時命名的參數是 clr ,所以 Connections 的信號處理器中可以直接使用它給 coloredText 對象復制。
好了,看看初始運行的效果,圖 12 :
圖 12 自定義信號之變色文本初始效果圖
圖 13 是我點擊了紅色的顏色選擇組件時的效果:
圖 13 選擇紅色后的效果
嗯,不知道你是否已經明白如何使用自定義信號?多練練吧。這個示例用到的 Component 和 Loader ,還請您先自行查閱 Qt 幫助來理解,后續我們有專門的文章來講述它們。
連接信號與槽
前面我們使用信號時,要么通過信號處理器,要么使用 Connections 對象。其實在 QML 中還有一種更一般的方式。先回想下 Qt C++ 中我們如何使用信號與槽…… QObject::connection() ,諾,木錯,就是它了。對應的,在 QML 中,其實 signal 是個對象,它也有一個 connect() 方法,你可以使用它連接到任意的方法上哦。有 connect() 就有 disconnect() ,正確, signal 對象的的確確有這兩個方法,允許我們使用它維護連接。
signal 對象的 connect() 方法允許你連接一個信號到另外一個信號或者方法。其實沒差別,信號本身也是個方法(函數)。當信號發射時,連接到信號上的其它信號或方法就會被調用。
signal 對象的這種連接方式,使用起來比信號處理器更加靈活。前面介紹信號處理器時,已經提到,信號處理器和信號是一對一的關系。而 signal 對象的這種連接方式,使得一個信號能夠連接多個方法。
舉個簡單的例子來看看如何使用吧。下面的代碼(來自 Qt 幫助), messageReceived 信號通過 connect() 方法連接到了三個方法上。
- Rectangle {
- id: relay;
- signal messageReceived(string person, string notice);
- Component.onCompleted: {
- relay.messageReceived.connect(sendToPost);
- relay.messageReceived.connect(sendToTelegraph);
- relay.messageReceived.connect(sendToEmail);
- relay.messageReceived("Tom", "Happy Birthday");
- }
- function sendToPost(person, notice) {
- console.log("Sending to post: " + person + ", " + notice);
- }
- function sendToTelegraph(person, notice) {
- console.log("Sending to telegraph: " + person + ", " + notice);
- }
- function sendToEmail(person, notice) {
- console.log("Sending to email: " + person + ", " + notice);
- }
- }
上面是信號連接方法的示例,實際上信號也可以連接信號。我們說了,信號本質是一個方法(函數),所以,信號連接信號等同於信號連接方法。下面是一個簡單的示例:
- Rectangle {
- id: forwarder;
- width: 100;
- height: 100;
- signal send();
- onSend: console.log("Send clicked");
- MouseArea {
- id: mousearea;
- anchors.fill: parent;
- onClicked: console.log("MouseArea clicked");
- }
- Component.onCompleted: {
- mousearea.clicked.connect(send);
- }
- }
這里我們給 Rectangle 定義了一個信號 send() ,在 Component.onCompleted 附加信號處理器中,把 MouseArea 對象的 clicked 信號連接到 Rectangle 的 send() 信號上。
K.O. !終於把 QML 中的信號與槽介紹完了。
溫故知新哦,回顧一下本系列的文章:Qt Quick 簡介
- QML 語言基礎
- Qt Quick 之 Hello World 圖文詳解
- Qt Quick 簡單教程
- Qt Quick 事件處理之信號與槽
- Qt Quick事件處理之鼠標、鍵盤、定時器
- Qt Quick 事件處理之捏拉縮放與旋轉
- Qt Quick 組件與對象動態創建詳解
- Qt Quick 布局介紹
- Qt Quick 之 QML 與 C++ 混合編程詳解
下一次,我們將學習如何在 Qt Quick 中處理常見的事件,包括按鍵、鼠標、定時器等。敬請關注。
http://blog.csdn.net/foruok/article/details/30028711