我无法从QML中读取javascript变量。我知道这似乎很容易,但这是一个特例:
我使用canvas3D生成大量3D Spheres,并且因为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%
哪个没用。我希望每次创建一个球体时都会移动条形。
你知道我该怎么办?
答案 0 :(得分:2)
您只看到0%和100%作为进度,因为initializeGL()
中的for循环在QML引擎响应更改的canvas3d.progress
值并更新{的值之前完全执行{1}}。 for循环和从progessBar.value
到progessBar.value
的属性绑定的更新在同一个线程中运行。
解决此问题的方法是仅调用canvas3d.progress
一步,然后生成CPU以更新进度。我的想法是使用单次定时器,自己调用initializeGL()
次并初始化第i次射击中的第i个速度。
逐步初始化函数将在test6.js中定义如下:
numSphere
在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
启动单次定时器意味着将事件放入主Qt事件循环中。定时器间隔到期后,计时器将触发。间隔为0ms只意味着计时器会在计时器事件到达事件队列(循环)前面的同时触发并执行onInitializeGL: timer.start()
。
在处理计时器事件之间,事件队列还将为QML引擎提供一些时间来更新onTriggered
的属性绑定。因此,您应该看到0到100之间的相当多的中间进度值。但是,您将看不到所有因为在发生属性绑定更新之前可能会处理多个计时器事件。如果要查看更多进度更新,可以简单地增加计时器间隔。