2017-03-05 61 views
3

我有两个JavaScript函数fun1fun2在QML,并要执行一个(fun2)陆续(fun1)结束后,更确切地说,我怎么在fun1ImageReader完成后开始fun2()ImageReader是通过继承QImageProvider用C++编写的函数,如下所示:的Javascript等待QML

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

的使用情况是,我要处理在C++中的图像,并且当该处理完成时,通过QML图片项目显示它。

+1

那么你的问题是什么?你不是已经根据你提供的代码在'func1()'之后执行'func2()'吗? – folibis

+0

我会建议一个接一个地打电话给他们。例如像代码[这里](http://stackoverflow.com/questions/42607709/javascript-waiting-in-qml)。是什么让你觉得他们不是一个接一个地被执行? – derM

+0

我认为你的问题是,'fun1()'只启动在另一个线程中异步执行的ImageReader.magic(photo)方法。所以你的问题应该是:*在'ImageReader'完成他的魔法之后,我该如何开始'fun2()',因为'fun1()'可能在此之前完成。所以'fun2()'在'fun1()'完成之后,'ImageReader.magic(photo)'完成之前执行。 – derM

回答

3

基本上你对如何处理这个

  1. 使异步处理两个选项通知它正在完成
  2. 投票结果的可用性

我不会推荐第二种方法,特别是在声明式环境中,所以让我们进一步研究选项之一。

对于C++和QML/JavaScript的,你再有通知基本上有两种选择

  1. 使用QObject信号机制
  2. 传递一个JavaScript回调到C++,并调用从那里

Qt的asnychronous QML API通常与前者一起完成,但如果您更喜欢后者,请查看QJSValue作为用于回调参数的C++数据类型。

0

我不太了解QML,我认为在普通JavaScript中你的代码应该可以工作。但我可以,如果建议你这个丑陋的方式它没有要求顺序:

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

谢谢。但它仍然不起作用。 'ImageReader.magic(photo);'是通过继承QImageProvider用C++编写的函数,它需要较长的时间来处理图像并返回QML。 – zzj

5

好吧,我只想为那些将要搜索相同解决方案的人进行总结。

至少有2种方式来做到这一点:

  • 从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(); 
}