从另一个Javascript脚本(Canvas3D)更新QML属性

从另一个Javascript脚本(Canvas3D)更新QML属性,javascript,qt,qml,Javascript,Qt,Qml,从QML读取javascript变量时遇到问题。我知道这似乎很容易,但这是一个特殊情况: 我正在使用canvas3D生成许多3D球体,由于指令非常长,我想显示一个进度条 为此,我做了以下工作: import "test6.js" as GLCode Item { id: mainview width: 1280 height: 768 visible: true // THE PROGRESS BAR ProgressBar { id : progressBar anc

从QML读取javascript变量时遇到问题。我知道这似乎很容易,但这是一个特殊情况:

我正在使用canvas3D生成许多3D球体,由于指令非常长,我想显示一个进度条

为此,我做了以下工作:

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中有一个属性名progress,我正试图从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;
}
这是没有用的。我更喜欢在每次创建球体时移动条


你知道怎么做吗?

你只看到0%和100%的进度,因为
initializeGL()
中的for循环在QML引擎响应
canvas3d.progress
的更改值和更新
progessBar.value
的值之前被完全执行。for循环和从
progessBar.value
canvas3d.progress
的属性绑定更新在同一线程中运行

解决此问题的方法是只调用
initializeGL()
一步,然后生成CPU以更新进度。我的想法是使用一个单次放炮计时器,它调用自己的
numSphere
时间并初始化第i次放炮中的第i个spere

逐步初始化功能将在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()
        }
    }
}
启动单次触发计时器意味着将事件放入主Qt事件循环。计时器在计时器间隔到期时触发。0毫秒的间隔仅仅意味着计时器在计时器事件到达事件队列(循环)的最前端时启动并执行
onTriggered


在处理计时器事件之间,事件队列还将给QML引擎一些时间来更新
progressBar.progress的属性绑定。因此,您应该看到许多介于0和100之间的中间进度值。但是,您不会看到全部,因为在属性绑定更新发生之前可能会处理多个计时器事件。如果您想看到更多的进度更新,只需增加计时器间隔。

您只看到0%和100%的进度,因为
initializeGL()
中的for循环在QML引擎响应
canvas3d.progress
的更改值并更新
progessBar.value
之前被完全执行。for循环和从
progessBar.value
canvas3d.progress
的属性绑定更新在同一线程中运行

解决此问题的方法是只调用
initializeGL()
一步,然后生成CPU以更新进度。我的想法是使用一个单次放炮计时器,它调用自己的
numSphere
时间并初始化第i次放炮中的第i个spere

逐步初始化功能将在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()
        }
    }
}
启动单次触发计时器意味着将事件放入主Qt事件循环。计时器在计时器间隔到期时触发。0毫秒的间隔仅仅意味着计时器在计时器事件到达事件队列(循环)的最前端时启动并执行
onTriggered

在处理计时器事件之间,事件队列还将给QML引擎一些时间来更新
progressBar.progress的属性绑定。因此,您应该看到许多介于0和100之间的中间进度值。但是,您不会看到全部,因为在属性绑定更新发生之前可能会处理多个计时器事件。如果您想看到更多进度更新,只需增加计时器间隔即可