Javascript在QML中等待

时间:2017-03-05 11:17:43

标签: qml qt5

我在QML中有两个javascript函数fun1fun2,并希望在另一个(fun2)完成后执行一个(fun1),更确切地说,如何完成fun2()中的ImageReader后,我是否可以fun1开始ImageReader是一个用C ++编写的函数,它继承QImageProvider,如下所示:

function fun1(){
    ImageReader.magic(photo);
}
function fun2(){
    myImg.source = ""; 
    myImg.source = "image://ImageReader";
}
fun1();
fun2();

使用场景是我想用C ++处理图像,当处理完成后,通过QML Image项显示它。

3 个答案:

答案 0 :(得分:5)

好的,我只想总结一下那些会搜索相同解决方案的人。

至少有两种方法可以做到:

  • 完成任务后,从C ++对象发出信号。
  • 将JS函数传递给C ++,这将在任务完成时调用。

测试C ++对象声明:

class MyItem : public QObject
{
    Q_OBJECT

public:
    MyItem(QObject *parent = 0);
    Q_INVOKABLE void someAsyncFunc();
    Q_INVOKABLE void someAnotherAsyncFunc(QJSValue value);

signals:
    void someAsyncFuncFinished();
};

测试C ++对象实现:

MyItem::MyItem(QObject *parent) :
QObject(parent) {}

void MyItem::someAsyncFunc()
{
    // do some work here
    emit someAsyncFuncFinished();
}

void MyItem::someAnotherAsyncFunc(QJSValue value) {
    // do some work here
    if (value.isCallable()) {
        value.call();
    }
}

将自定义项目注册为单身人士:

static QObject *my_singleton_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
{
    Q_UNUSED(engine)
    Q_UNUSED(scriptEngine)
    static MyItem *item = nullptr;
    if(!item)
        item = new MyItem();
    return item;
}

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    qmlRegisterSingletonType<MyItem>("Qt.MyTest", 1, 0, "MyItem", my_singleton_provider);

    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    return app.exec();
}

所以测试它的QML文件:

<强> 1。任务完成时触发的信号

Item {
    id: testItem

    function func1()
    {
        console.log("func1 executing...")
        MyItem.someAsyncFuncFinished.connect(func2);
        MyItem.someAsyncFunc();
    }

    function func2()
    {
        console.log("func2 executing...")
    }

    Component.onCompleted: func1();
}

<强> 2。将JS函数传递给C ++:

Item {
    id: testItem

    function func1()
    {
        console.log("func1 executing...")
        MyItem.someAnotherAsyncFunc(func2);
    }

    function func2()
    {
        console.log("func2 executing...")
    }

    Component.onCompleted: func1();
}

答案 1 :(得分:3)

基本上,你有两种方法可以解决这个问题

  1. 让异步进程通知它已完成
  2. 对结果的可用性进行轮询
  3. 我不推荐第二种方法,特别是在声明性环境中,所以让我们进一步研究选项一。

    对于C ++和QML / JavaScript之间的通知,您基本上还有两个选项

    1. 使用QObject信号机制
    2. 将JavaScript回调传递给C ++并从那里调用
    3. Qt的异步QML API通常使用前者完成,但如果您更喜欢后者,请查看QJSValue作为用于回调参数的C ++数据类型。

答案 2 :(得分:0)

我对QML了解不多,我认为在普通的JavaScript中你的代码应该可行。但是,如果它没有按顺序调用,我可以建议你这种丑陋的方式:

function fun1() {
    ImageReader.magic(photo);
    return 1;
}
function fun2(wait){
    if(wait==1)
    {
        myImg.source = ""; 
        myImg.source = "image://ImageReader";
    }
}
fun2(fun1());