2017-09-13 60 views
0

例如是否保證兒童的初始化順序與它們在源代碼中出現的順序相匹配?是否指定了Qt Quick子項的加載順序?

注意:「初始化孩子」的意思是「孩子及其所有孩子,後代,綁定等的初始化」。

+0

這是一棵樹,按順序創建對象。對於綁定,沒有保證,順序是任意的。它發生在一個單獨的過程中,並且可能需要多次傳遞,具體取決於表達式層次結構。作爲一個經驗法則,您不應該依賴比根對象上的整個QML文件更細的顆粒。如果您想要更嚴格地控​​制訂單,則必須實例化樹。 – dtech

+0

@dtech:「按順序創建對象」。 - 但是*什麼*命令? :) –

+0

自然樹的順序,從根到頂葉。我不知道具體的實現,但是通用邏輯規定您迭代樹並創建每個對象,推送並彈出當前要用作父級的分支對象。在父母之前創建孩子的可能性很小,然後父母被創建,然後你回到父母所有的孩子...... – dtech

回答

1

一個簡單的測試可以用來驗證對象創建的順序。

class Test : public QQuickItem { 
    Q_OBJECT 
    public: 
    Test(QQuickItem * p = 0) : QQuickItem(p) { qDebug() << this; } 
}; 

然後:

Test { 
    objectName: "a" 
    Component.onCompleted: console.log(objectName, this) 
    Test { 
     objectName: "b" 
     Component.onCompleted: console.log(objectName, this) 
     Test { 
     objectName: "c" 
     Component.onCompleted: console.log(objectName, this) 
     } 
     Test { 
     objectName: "d" 
     Component.onCompleted: console.log(objectName, this) 
     } 
    } 
    Test { 
     objectName: "e" 
     Component.onCompleted: console.log(objectName, this) 
    } 
    } 

其中給出的輸出:

Test(0x6a7378, parent=0x0, geometry=0,0 0x0) 
Test(0x6a73d8, parent=0x0, geometry=0,0 0x0) 
Test(0x6a7438, parent=0x0, geometry=0,0 0x0) 
Test(0x6a7498, parent=0x0, geometry=0,0 0x0) 
Test(0x6a74f8, parent=0x0, geometry=0,0 0x0) 
qml: a Test(0x6a7378, "a") 
qml: e Test(0x6a74f8, "e") 
qml: b Test(0x6a73d8, "b") 
qml: d Test(0x6a7498, "d") 
qml: c Test(0x6a7438, "c") 

這表明對象構造確實叫底部到頂部。

另請注意,onCompleted的順序是不同的,具體取決於該處理程序的安裝位置。如果你換TestObj.qml這樣的:

Test { 
    id: rectangle 
    Component.onCompleted: console.log(objectName, this) 
} 

,並宣佈這樣的結構:

Obj { 
    objectName: "a" 
    Obj { 
     objectName: "b" 
     Obj { 
     objectName: "c" 
     } 
     Obj { 
     objectName: "d" 
     } 
    } 
    Obj { 
     objectName: "e" 
    } 
    } 

然後你得到一個一致的「回鋒」輸出,你沒有在得到第一種方案:

Test(0x4b2458, parent=0x0, geometry=0,0 0x0) 
Test(0x4b24b8, parent=0x0, geometry=0,0 0x0) 
Test(0x4b2518, parent=0x0, geometry=0,0 0x0) 
Test(0x4b2578, parent=0x0, geometry=0,0 0x0) 
Test(0x50f9d68, parent=0x0, geometry=0,0 0x0) 
qml: e Test(0x50f9d68, "e") 
qml: d Test(0x4b2578, "d") 
qml: c Test(0x4b2518, "c") 
qml: b Test(0x4b24b8, "b") 
qml: a Test(0x4b2458, "a") 

然而,這一切都反映了對象創建的順序,不會反對完成,其中涉及一堆其他的東西,它可以執行d以任意順序依賴於結合表達結構。

總之,你不應該真的依賴於這個順序,如果你這樣做,你做錯了。你不應該依賴任何比整個QML源代碼樹完成更好的東西,qtquick引擎本身會小心地延遲綁定表達式的初始化,直到整個對象樹完成爲止,所以你不會遇到問題它會自動發生,但是依賴於更低層次和更細粒度的任何東西都是設計中的一個潛在缺陷,應該避免。給你的對象id,併爲整個qml文件執行一個單獨的初始化表達式,如果你想要更明確的命令初始化鉤起來的東西在一起。該表達式中的語句將按照它們定義的順序執行。

+0

* [...]你不應該真的依賴於該順序[...] *該訂單變成有趣的是,當有人忘記通過屬性暴露兒童,並且你需要通過'children [index]'來訪問這些孩子,因爲他們按照創建的順序被追加到這個列表中(除非他們後來被重新設置,那就是) - 因此,如果你想樣式'QtQuick.Controls 1.x'-對象總是很好,你可以通過源代碼輕鬆地確定在這個列表的哪個位置上你會找到你想要改變屬性的部分。 – derM

+0

這不被認爲是一個「穩定」的界面,我個人不會那樣做。該訂單可能會因多種原因而發生變化。我寧願複製控制源並且接口我需要的東西。 – dtech

+0

我認爲它是一個穩定的接口,據我所知,它不再被維護,所以更改不太可能。所以,讓我們說:足夠穩定。 – derM