5

在我的代码中,我正在循环创建 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);
}

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

4

3 回答 3

10

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

  1. 阅读有关WorkerScript元素的信息。它允许您通过将 javascript 函数作为线程运行来执行某些操作。

注意:如文档中所述,有一个限制:

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

只要看看,它是否适合您的特定用例。

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

于 2013-04-16T13:02:38.820 回答
3

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

于 2013-04-16T19:59:53.573 回答
3

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

  • 使用incubateObject而不是createObject
  • 不要在单个 (16ms) 帧内创建所有按钮:使用计时器将按钮的创建分散到多个帧
于 2015-12-11T15:20:28.510 回答