1、效果
代碼參考B站視頻:https://www.bilibili.com/video/av36584062
功能:點擊左邊,會發出信號,右邊會有個顏色動畫,然后計數+1
2、分析:
一共有兩個對象,他們很多屬性都差不多,如可變顏色、原型、可變text..所以可以聲明一個Circle對象,然后Sender和Recver都繼承它;
能夠通過Sender控制Recver,那么Sender一定有信號發出,然后Recver有一個函數用於狀態改變;
應該在發出信號的地方即Sender里,連接信號與槽,根據總結:https://www.cnblogs.com/judes/p/11243242.html,這里屬於QML的信號QML的槽,所以應該直接使用signal.connect(slot)的形式,但是怎么在Sender中訪問到Recver的槽函數呢?
可以這樣:在Sender里加一個Recver屬性,初始化為null,然后在這個Recver的onRecverChanged回調中,connect。
3、圖形基類Circle.qml
import QtQuick 2.0 Item { width: 200 height: 200 property alias circlrColor: circlr.color property alias contentText: content.text Rectangle { id: circlr color: "#f94141" radius: width*0.5 anchors.fill: parent Text { id: content x: 93 y: 94 color: "#e5d9d9" text: qsTr("Text") verticalAlignment: Text.AlignVCenter horizontalAlignment: Text.AlignHCenter anchors.verticalCenter: parent.verticalCenter anchors.horizontalCenter: parent.horizontalCenter font.pixelSize: 30 } } }
這里需要注意:
property alias circlrColor: circlr.color
property alias contentText: content.text
我是直接在設計界面直接導出別名屬性:
這個別名屬性即alias,外界可以通過改變這個變量直接改變到對應的控件屬性。
4、Sender.qml
import QtQuick 2.0 Circle { id: sender property int counter: 0 signal sendSignal(string value) property Recver target:null onTargetChanged: { sendSignal.connect(target.recvSlot) } MouseArea { anchors.fill: parent onClicked: { sender.counter++ sender.sendSignal(counter) } onPressed: { sender.circlrColor="red" } onReleased: { sender.circlrColor="blue" } } }
核心就是在紅色的地方,將null Recver作為自己的屬性,然后在main里賦值,當賦值成功就連接信號與槽
5、Recver.qml
import QtQuick 2.0 import QtQuick 2.7 Circle { id: recver function recvSlot(value) { contentText=value; colorNotify.running=true; } SequentialAnimation on circlrColor { id: colorNotify running: false ColorAnimation { from: "red" to: "blue" duration: 200 } ColorAnimation { from: "blue" to: "red" duration: 200 } } }
這里有個重點就是紅色部分,即序列動畫,里面的動畫按照順序執行,看文檔或者資料都沒有SequentialAnimation on circlrColor的用法,這里是直接作用於顏色【很多QML的騷用法在文檔里都找不到,這也是我認為阻擋我學習QML的難處】
6、main.qml
import QtQuick 2.9 import QtQuick.Window 2.2 Window { id: window visible: true width: 640 height: 480 title: qsTr("Hello World") Background { id: background anchors.fill: parent Recver { id: recver x: 359 y: 128 circlrColor: "#ff0000" contentText: "Recver" anchors.verticalCenterOffset: 0 anchors.verticalCenter: parent.verticalCenter } Sender { id: sender x: 79 y: 140 target: recver circlrColor: "#0000ff" contentText: "Sender" anchors.verticalCenterOffset: 0 anchors.verticalCenter: parent.verticalCenter } } }
Background可不管,就是個簡單的背景qml