2017-08-04 60 views
1

我有一個來自文件系統的加載的qml文件發生了變化,但是由於第一次加載時它也被緩存,即使Loader通過將源組件設置爲undefined而被「重置」,它也不刷新。如何最正確/有效地刷新源代碼已更改的項目?

一個similar questions has been asked before,但是我想走得更遠的幾個原因:

  • 接受的回答有建議使用的engine->trimComponentCache()不幸的作品只有一次,然後停止,沒有進一步的更新會反映
  • 在下面的評論中,OP建議engine->clearComponentCache()工作,並且實際上它每次都是。然而此方法的文檔中有我有點不安與它的使用方面:

此功能使以前由發動機加載的所有組件 的屬性元數據被破壞。所有先前加載的 組件和屬性綁定對於創建的所有現存對象 將從這些組件中停止運行

這當然聽起來很可怕,尤其是部分大膽的,因爲我不重裝我的整個應用程序,這是一個相當大的應用程序,它需要保持完整,而在同一時間刷新的只是一小部分那個特定的外部qml文件來反映它的變化。

第二部分你聽起來有點更promissing:

該函數返回發動機,其中它不包含任何 擔載成分的數據的狀態。這對於重新加載之前組件集的較小子集或加載以前加載的組件的新版本 可能很有用。

一旦組件高速緩存已被清除,在創建任何新對象之前必須先加載組件 。

因此,它給人的印象是這種方法可以用來在不破壞現有代碼的情況下重新加載子集。然而,即便是這樣,它也會涉及很多額外的工作來爲新實例化的對象重新構建所有緩存,而不是簡單地爲特定的更改的qml源清理緩存。

此外,我一直在考慮一個更復雜的解決方案,涉及創建一個自定義QML元素,它本質上是一個全新的QML引擎的包裝,呈現給FBO並將輸出顯示爲對象我的「主」引擎,從而完全隔離這兩個引擎。然而我並不是那麼熱衷於做所有額外的工作,並且引入了另一個整個運行引擎的開銷。

那麼有什麼想法?

回答

1

直到有人提出了更好的解決方案,我同時發現trimComponentCache()只有在清除,修整和重置順序發生時纔會失敗,即在同一個事件循環中。它的工作原理,每次當事件循環被允許與旋轉的,所以我去了這個解決方案,它每一次的作品:

Timer { 
    id: updater 
    interval: 1 
    repeat: true 
    property int s: 0 
    onTriggered: { 
     switch (s) { 
     case 0: 
     loader.sourceComponent = undefined 
     ++s 
     break 
     case 1: 
     Aux.trim() 
     ++s 
     break 
     case 2: 
     loader.source = "file:/d:/Rect.qml" 
     s = 0 
     stop() 
     } 
    } 
    } 

所以更新通過啓動計時器發出的,它會清除裝載機一個週期,修剪下一個緩存,並重新加載源代碼並在最後停止,重置加載器及其狀態。

相關問題