2016-04-06 73 views
0

我無法從QML讀取JavaScript變量。我知道這似乎很容易,但這是一個特殊的情況:從另一個Javascript腳本(Canvas3D)更新QML屬性

我使用canvas3D生成大量的3D球體,而且由於instenciation非常長,我想顯示一個進度條。

爲了做到這一點,我已經做到了這一點:

import "test6.js" as GLCode 

Item { 
id: mainview 
width: 1280 
height: 768 
visible: true 



// THE PROGRESS BAR 

ProgressBar { 
    id : progressBar 
    anchors.centerIn: parent 
    value: canvas3d.progress 
    z:1 
} 


//THE CANVAS3D (WebGL) 
Canvas3D { 
    id: canvas3d 
    anchors.fill: parent 
    focus: true 

    property double progress:0 //MY VARIABLE I WANT TO UPDATE FROM test6.js 


    property var list : [] 

    // Emitted when one time initializations should happen 
    onInitializeGL: { 
     GLCode.initializeGL(canvas3d); 
    } 

我在canvas3d屬性名稱的進步,我試着從test6.js腳本修改

在initializeGL每次我更新的進度值(canvas3d)功能,我添加了一個球:現在

for (i = 0; i < spheresNum; i ++) { 

    var x = list[i][0]; 
    var y = list[i][1]; 
    var z = list[i][2]; 
    drawSphere(x,y,z,i); 
    canvas3d.progress = i/spheresNum*100; 
} 

,問題是,我得到的進度更新值只有當initializeGL()結束。現在它是這樣的:

Progress Bar to 0% 
(Waiting for all the sphere to be instanciated) 
(initializeGL() ends) 
Progress Bar to 100% 

這是沒用的。每次創建球體時,我都希望酒吧移動。

你知道我該怎麼做?

回答

2

由於initializeGL()中的for循環在QML引擎將響應更改後的值canvas3d.progress並更新progessBar.value的值之前,您只能看到0%和100%的進度。 for循環和從progessBar.valuecanvas3d.progress的屬性綁定更新在同一個線程中運行。

解決此問題的方法是僅調用initializeGL()一步,然後生成用於更新進度的CPU。我的想法是使用一個單次計時器,它自己調用numSphere次,並初始化第i個鏡頭中的第i個鏡頭。

分步初始化函數將在test6.js定義如下:

function initializeGLSphere(i) { 
    var x = list[i][0]; 
    var y = list[i][1]; 
    var z = list[i][2]; 
    drawSphere(x,y,z,i); 
} 

Canvas3d的實例後,添加單次計時器:

property int currentSphere = 0 

Timer { 
    id: timer 
    repeat: false 
    interval: 0 
    onTriggered: { 
     GLCode.initializeGLSphere(currentSphere) 
     ++currentSphere 
     progessBar.progress = currentSphere/GLCode.numSpheres 
     if (currentSphere < GLCode.numSpheres) { 
      timer.restart() 
     } 
    } 
} 

計時器開始於onInitializeGL

onInitializeGL: timer.start() 

開始單次計時器意味着一個Event被放入主Qt事件循環中。一旦定時器間隔到期,定時器就會啓動。間隔0ms只是意味着定時器事件觸發並儘快執行onTriggered定時器事件到達事件隊列(循環)的前面。

在定時器事件之間工作,事件隊列也會給QML引擎一些時間來更新progressBar.progress的屬性綁定。因此,您應該會看到介於0和100之間的相當多的中間進度值。但是,您不會看到全部,因爲可能會在發生屬性綁定更新之前處理多個計時器事件。如果你想看到更多的進度更新,你可以簡單地增加計時器間隔。

+0

非常感謝:) – ElevenJune