2013-11-21 53 views
3

@TheBootroo提供的答案在這裏:link如何在QML中訪問動態/隨機加載的Repeater項目?

提供了一種在QML文件/屏幕/視圖之間加載和更改的方法。但是,像這樣做時,如何使用信號和插槽?

可以使用Repeater :: itemAt(index)方法訪問由repeater創建的項目,但由於我不知道按什麼順序加載項目,我不知道索引screen2,screen3, screen4等是在。

有什麼辦法可以解決這個問題嗎?還是必須在啓動時實例化內存中的所有屏幕?

我下面的代碼:

main.qml:

//List of screens 
    property variant screenList: [ 
     "main", 
     "screen2", 
     "screen3", 
     ... 
    ] 

    //Set this to change screen 
    property string currentScreen: "main" 


    Repeater { 
     id: screens 
     model: screenList 
     delegate: Loader { 
      active: false; 
      asynchronous: true 
      anchors.fill: parent 
      source: "%1.qml".arg(modelData) 
      visible: (currentScreen === modelData) 
      onVisibleChanged: { 
       loadIfNotLoaded() 
      } 
      Component.onCompleted: { 
       loadIfNotLoaded() 
      } 

      function loadIfNotLoaded() { 
       //To load start screen 
       if(visible && !active) { 
        active = true; 
       } 
      } 
     } 
    } 

    Connections { 
     target: screens.itemAt(indexHere) 
     //screen is here the string passed with the signal from screen2. 
     onChangeScreen: currentScreen = screen 
    } 

    Button { 
     id: button1 
     text: "Go To Screen 2" 
     onClicked: { 
      currentScreen = "screen2" 
     } 
    } 

而且在screen2.qml:

signal changeScreen(string screen) 

Button { 
    text: "Go To Main" 
    onClicked: { 
     changeScreen("main") 
    } 
} 

回答

4

人們可以通過訪問由中繼器創建項目Repeater :: itemAt(index)方法,但由於我不知道按什麼順序加載項目,我不知道索引screen2,screen3,screen4等是在什麼位置。

Repeater實例化的項目順序實際上是定義的 - 項目將按照模型的順序實例化,因此在您的情況下,「main」將是第一個,然後是「screen2」等等。現在,Repeater中的每個項目都是一個Loader - Repeater將按照定義的順序創建3個Loaders。裝載機自己根據需要加載其源項目。

我認爲你的代碼中唯一缺少的是連接指的是加載器,但你需要它來引用加載器創建的項目。因此,改變連接到

Connections { 
    target: screens.itemAt(indexHere).item 
    onChangeScreen: currentScreen = screen 
} 

注意附加.item

解決此問題之後,還有一個額外的問題:Repeater在Connections元素創建時尚未實例化其項目,因此screens.itemAt(indexHere)將返回null。解決這個問題的方法之一是使用一個currentIndex屬性,而不是一個currentScreen屬性和使用,在爲target綁定,並設置currentIndex直放站已經實例及其項目後:

property int currentIndex: -1 
... 
Connections { 
    target: screens.itemAt(currentIndex).item 
    ... 
} 
Component.onCompleted: currentIndex = 0 

即使容易很可能是把Connections元素放在Repeater的委託中,即有3個連接而不是一個(假設你有3個屏幕)。

+0

這在某種程度上工作,但緩慢/越野車。這可能是由於其他小問題,所以我接受了你的答案。 – Phat

相關問題