Item 0:編碼規範
本節提供有關如何格式化屬性,信號和函數的順序,以使事情變得輕鬆並快速切換到相關代碼塊。
QML對象屬性始終按以下順序構造:
- id
- 屬性聲明
- 信號聲明
- 對象聲明
- 狀態(States)
- 變換(Transitions)
- 信號處理器(Signal handlers)
- 子對象
- 可視對象
- Qt提供的不可見對象
- 自定義的不可見對象
- QtObject所包裝的私有數據
- JavaScript函數
Rectangle {
id: photo
property bool thumbnail: false // 屬性聲明
property alias image: photoImage.source
signal clicked // 信號聲明
x: 20
y: 20
height: 150
color: "gray" //對象聲明
width: { // 較大的綁定
if (photoImage.width > 200) {
photoImage.width;
}
else {
200;
}
}
states: State { // 狀態
name: "selected"
PropertyChanges { target: border; color: "red" }
}
transitions: Transition { // 變換
from: ""; to: "selected"
ColorAnimation { target: border; duration: 200 }
}
onSomeEvent: {
}
Rectangle { // 子對象 - 可視對象
id: border
anchors.centerIn: parent; color: "white"
Image { id: photoImage; anchors.centerIn: parent }
}
Timer { } // 子對象 - Qt提供的不可見對象
MyCppObject { } // 子對象 - 自定義的不可見對象
QtObject {
id: privates
property var privateProperty: null
}
function doSomething(x) { // JavaScript 函數
return x + photoImage.width
}
}
信號處理順序
當處理在Item
上的信號時,要始終記得將Component.onCompleted
放在最後一行.
// 錯誤的示例
Item {
Component.onCompleted: {
}
onSomeEvent: {
}
}
// Correct
Item {
onSomeEvent: {
}
Component.onCompleted: {
}
}
放在末尾是爲了更好的符合心裏預期:在組件構造結束時會觸發Component.onCompleted。
如果一個Item中有多個信號處理程序,則將行數最少的那些處理程序放在頂部。 隨着實現線的增加,處理程序也向下移動。 唯一的例外是Component.onCompleted信號,它始終放在底部。
// 錯誤示例
Item {
onOtherEvent: {
// Line 1
// Line 2
// Line 3
// Line 4
}
onSomeEvent: {
// Line 1
// Line 2
}
}
// 正確示例
Item {
onSomeEvent: {
// Line 1
// Line 2
}
onOtherEvent: {
// Line 1
// Line 2
// Line 3
// Line 4
}
}
屬性的順序
第一個賦值的屬性必須是id。 如果要聲明組件的自定義屬性,則聲明始終位於第一個屬性賦值的上方。
// 錯誤示例
Item {
someProperty: false
property int otherProperty: -1
id: myItem
}
// 正確示例
Item {
id: myItem
property int otherProperty: -1
someProperty: false
}
屬性賦值還有一些預定義的順序。 順序如下:
- id
- x
- y
- width
- height
- anchors
這裏的目標是將最明顯和定義最明確的屬性放在頂部,以方便訪問和查看。 例如,對於圖像,我們可能決定將sourceSize也放置在anchors上方。
如果同時還有屬性賦值和信號處理器,請確保始終將屬性賦值放在信號處理程序上方。
// 錯誤示例
Item {
onOtherEvent: {
}
someProperty: true
onSomeEvent: {
}
x: 23
y: 32
}
// 正確示例
Item {
x: 23
y: 32
someProperty: true
onOtherEvent: {
}
onSomeEvent: {
}
}
如果將屬性賦值與信號處理器混合在一起,通常很難看到它們。 這就是爲什麼我們將分配放在信號處理程序之上。
函數順序
儘管QML中沒有私有和公共函數,但是我們可以通過使用QtObject進行包裝還達成類似的效果
公共函數實現始終放在文件的最底部。
// 錯誤示例
Item {
function someFunction() {
}
someProperty: true
}
// Correct
Item {
someProperty: true
onOtherEvent: {
}
onSomeEvent: {
}
function someFunction() {
}
}
動畫
當使用Animation的任何子類時,尤其是嵌套的子類(如SequentialAnimation)時,請嘗試減少一行中的屬性數量。 一段時間後,很難推理出同一行中的2-3個以上的賦值。
由於在我們的腦海中很難想象動畫,因此我們將受益於使動畫儘可能簡單,因爲它們每幀執行一次。 嘗試給他們提供有意義的ID或對象名稱,以幫助我們將來在出現問題時對動畫進行自我調試。
// 壞的例子
NumberAnimation { target: root; property: "opacity"; duration: root.animationDuration; from: 0; to: 1 }
// Depends on your convention. The line does not exceed 80 characters.
PropertyAction { target: root; property: "visible"; value: true }
// 好的例子
SequentialAnimation {
PropertyAction {
target: root
property: "visible"
value: true
}
NumberAnimation {
target: root
property: "opacity"
duration: root.animationDuration
from: 0
to: 1
}
}
可以放棄部分組件的id
如果一個組件不需要被如何訪問,請避免設置id屬性。 這樣,我們就不會混淆命名空間中的id,或者更可能的產生明明衝突.
最好使用id最多3-4個字符的縮寫,以便在查找某個組件(例如TextBox)時,只需鍵入tb即可列出所有文本框的ID。
命名規則爲[組件名縮寫] [組件具體描述],例如tbEmail,btnLogIn
TextBox {
id: tbEmail
}
Button {
id: btnSubmit
}
CheckBox {
id: cbAgreement
}
確保最外層的組件使用root作爲id
屬性賦值
分配分組的屬性時,如果只更改一個屬性,則始終首選點號。 否則,請始終使用組符號。
Image {
anchors.left: parent.left // 通過. 來訪問
sourceSize { // 通過組符號來訪問
width: 32
height: 32
}
}
在同一文件中的不同位置將組件分配給Loader的sourceComponent時,請考慮使用相同的實現。 例如,在以下示例中,存在同一組件的兩個實例。 如果兩個SomeSpecialComponent都是相同的,則最好將SomeSpecialComponent包裝在Component中。
// BEGIN 壞的示例.
Loader {
id: loaderOne
sourceComponent: SomeSpecialComponent {
text: "Some Component"
}
}
Loader {
id: loaderTwo
sourceComponent: SomeSpecialComponent {
text: "Some Component"
}
}
// END 壞的示例.
// BEGIN 好的示例.
Loader {
id: loaderOne
sourceComponent: specialComponent
}
Loader {
id: loaderTwo
sourceComponent: specialComponent
}
Component {
id: specialComponent
SomeSpecialComponent {
text: "Some Component"
}
}
// END 好的示例.
這樣可以確保無論何時對specialComponent進行更改,它都將在所有裝載程序中生效。 在壞的的示例中,我們將必須重複相同的更改。
Import語句
Import在QML中花費時間。而且,如果我們正在開發系統規格較低的設備,那麼我們將需要儘可能地優化。在這種情況下,請嘗試最小化我們在QML文件中使用的導入次數。
如果還需要導入JavaScript文件,請確保在QML文件和JavaScript文件中都不包含相同的模塊。 JavaScript文件共享從QML文件導入的內容,因此我們可以使用用它。
如果不使用QML中導入的modules,請考慮將import語句移至JavaScript文件。但是請注意,一旦在JavaScript文件中導入了某些內容,導入內容將不再共享。有關完整規則,請參見此處。
另外,我們還可以使用Qt.include()複製包含文件的內容,而不必擔心導入共享規則。
導入順序
導入其他模塊時,請按照以下順序進行:
- Qt模塊
- 第三方模塊
- 本地C ++模塊導入
- QML文件夾導入