QML:在并行线程中运行函数

时间:2013-04-15 22:05:40

标签: multithreading parallel-processing qml

在我的代码中,我在循环中创建16x16按钮,这需要几秒钟。

onCreateField:
{
    for(var i=0;i<fieldWidth;i++)
    {
        for(var j=0;j<fieldHeight;j++)
        {
            createButton(i, j);
        }
    }
}

function createButton(x, y)
{
    __buttonX = x;
    __buttonY = y;

    __component = Qt.createComponent("GameButton.qml");

    if(__component != null)
        continueButtonCreation();
    else
        __component.ready.connect(continueButtonCreation);
}

function continueButtonCreation()
{
    var button = __component.createObject(field, {"row": __buttonY, "column": __buttonX});

     if (button == null) {
         // Error Handling
         console.log("Error creating object");

         return;
     }

     updateValveState.connect(button.stateUpdated);
     button.buttonClicked.connect(buttonClicked);

     field.clearField.connect(button.release);
}

创建按钮的功能运行时,应用程序冻结。我希望在此函数运行时显示加载动画。那么,如何在并行线程中运行此函数以避免冻结?

3 个答案:

答案 0 :(得分:10)

要在线程中工作,您有两种可能的方法:

  1. 了解WorkerScript元素。它允许您通过将javascript函数作为线程运行来执行某些操作。
  2. 注意:如文档中所述,但存在限制:

      

    由于WorkerScript.onMessage()函数是单独运行的   线程,JavaScript文件在与上下文不同的情况下进行评估   主要的QML引擎。这意味着与普通的JavaScript不同   导入QML的文件,上例中的script.js   无法访问QML的属性,方法或其他属性   item,也不能访问QML对象上设置的任何上下文属性   通过QDeclarativeContext。此外,还有限制   可以传递给工作者脚本的值的类型。   有关详细信息,请参阅sendMessage()文档。

    请注意,如果您的特定用例符合要求。

    2 。实现 heavy 的功能作为C ++线程。每当需要时,生成一个信号以在C ++端启动该线程。完成后,如果需要,将数据从C ++传回Qml。

答案 1 :(得分:1)

正如您在其他帖子中可能已经确定或未确定的那样,您无法并行加载QML对象。根据您的情况,您可能应该使用带有呈现按钮的委托的GridView。这允许底层代码有效地呈现按钮,而不是在javascript中顺序创建它们。

答案 2 :(得分:1)

不阻止UI的其他选项可能是

  • 使用incubateObject代替createObject
  • 不要在单个(16ms)帧内创建所有按钮:使用Timer在多个帧上分布按钮的创建