2016-04-06 14 views
0

Ich habe Probleme beim Lesen einer JavaScript-Variable aus QML. Ich weiß, das scheint einfach, aber das ist ein besonderer Fall:Aktualisieren einer QML-Eigenschaft von einem anderen JavaScript-Skript (Canvas3D)

Ich benutze canvas3D zum Generieren von vielen 3D-Kugeln und, da die Intentionierung wirklich lang ist, möchte ich einen Fortschrittsbalken anzeigen.

, das zu tun, ich habe dies getan:

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); 
    } 

ich einen Eigenschaftsnamen Fortschritt in meinem Canvas3D, die ich aus dem test6.js Skript

Im initializeGL zu ändern bin versucht, (Canvas3D) Funktion, die ich den Wert des Fortschritts bin Aktualisieren jedes Mal, wenn ich eine Kugel hinzu:

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; 
} 

Nun, das Problem ist, dass ich den aktualisierten Wert des Fortschritts erhalten nur, wenn initializeGL() beendet. Im Moment ist es wie folgt:

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

Was ist nutzlos. Ich würde es vorziehen, wenn sich die Leiste jedes Mal bewegt, wenn eine Kugel erstellt wird.

Wissen Sie, wie kann ich das tun?

Antwort

2

Sie sehen nur 0% und 100% als Fortschritt, weil die for-Schleife in initializeGL() voll, bevor der Motor auf den geänderten Wert von canvas3d.progress reagieren QML ausgeführt wird, und den Wert von progessBar.value aktualisieren. Die For-Schleife und die Aktualisierung der Eigenschaft Bindung von progessBar.value bis canvas3d.progress laufen im selben Thread.

Die Lösung dieses Problems besteht darin, initializeGL() nur für einen Schritt aufzurufen und dann die CPU zur Aktualisierung des Fortschritts zu liefern. Meine Idee wäre es, einen Single-Shot-Timer zu verwenden, der sich selbst numSphere nennt und den i-ten Spere im i-ten Schuss initialisiert.

Die schrittweise Initialisierungsfunktion würde in test6.js wie folgt definiert werden:

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() 
     } 
    } 
} 

Der Timer:

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

Nach dem Beispiel von Canvas3d, können Sie die Single-Shot-Timer hinzufügen wird gestartet in onInitializeGL:

Start Ein Single-Shot-Timer bedeutet, dass ein Event in die Haupt-Qt-Ereignisschleife gelegt wird. Der Timer wird nach Ablauf des Timer-Intervalls ausgelöst. Ein Intervall von 0 ms bedeutet einfach, dass der Timer ausgelöst wird und ausgeführt wird, sobald das Timer-Ereignis die Ereigniswarteschlange (Schleife) erreicht.

Zwischen den Zeitgeberereignissen wird der QML-Engine durch die Ereigniswarteschlange auch einige Zeit zur Verfügung gestellt, um die Eigenschaftsbindung für progressBar.progress zu aktualisieren. Sie sollten also einige Zwischenfortschrittswerte zwischen 0 und 100 sehen. Sie werden jedoch nicht alle anzeigen, da mehrere Timerereignisse behandelt werden können, bevor eine Aktualisierung der Eigenschaftenbindung erfolgt. Wenn Sie mehr Fortschrittsupdates sehen möchten, können Sie einfach das Zeitgeberintervall erhöhen.

+0

Vielen Dank :) – ElevenJune

Verwandte Themen