QML中的Javascript等待

QML中的Javascript等待,qml,qt5,Qml,Qt5,我在QML中有两个javascript函数fun1,fun2,我想在一个又一个(fun1)完成后执行一个(fun2),更准确地说,在fun1中的ImageReader完成后如何启动fun2() IVIDERADADER 是C++继承的一个函数,继承了 QImageProvider ,如下: function fun1(){ ImageReader.magic(photo); } function fun2(){ myImg.source = ""; myImg.sour

我在QML中有两个javascript函数
fun1
fun2
,我想在一个又一个(
fun1
)完成后执行一个(
fun2
),更准确地说,在
fun1
中的
ImageReader
完成后如何启动
fun2()<代码> IVIDERADADER <代码>是C++继承的一个函数,继承了<代码> QImageProvider <代码>,如下:

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

使用场景是,我想在C++中处理一个图像,当处理完成时,用QML图像项显示它。p> 我对QML了解不多,我认为在普通JavaScript中,您的代码应该可以工作。但如果不是按顺序调用,我可以向您推荐这种丑陋的方式:

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

基本上,你有两个选择来解决这个问题

  • 使异步进程通知它正在完成
  • 调查结果的可用性
  • 我不推荐第二种方法,尤其是在声明性环境中,所以让我们进一步研究选项一

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

  • 使用
    QObject
    信号机制
  • 将JavaScript回调传递给C++,并从那里调用

  • AsQualQualQualAPI通常是用前者来完成的,但是如果你喜欢后者,请看<代码> QJSValue作为回调参数使用的C++数据类型。< /P> < P> OK,我只想对那些搜索相同的解决方案的人进行总结。 至少有两种方法可以做到这一点:

    • 任务完成时发出C++对象的信号。
    • 将JS函数传递给C++,当任务完成时将调用它。

    <强>测试C++对象声明:>P/>

    类MyItem:公共QObject
    {
    Q_对象
    公众:
    MyItem(QObject*parent=0);
    Q_可调用的void someAsyncFunc();
    Q_可调用的void someAnotherAsyncFunc(QJSValue);
    信号:
    void someAsyncFuncFinished();
    };
    

    <强>测试C++对象实现:>/P>

    MyItem::MyItem(QObject*parent):
    QObject(父项){}
    void MyItem::someAsyncFunc()
    {
    //在这里做些工作
    发出someAsyncFuncFinished();
    }
    void MyItem::someAnotherAsyncFunc(QJSValue){
    //在这里做些工作
    if(value.isCallable()){
    value.call();
    }
    }
    
    将自定义项目注册为单个项目:

    静态QObject*my_singleton_提供程序(QQmlEngine*engine、QJSEngine*scriptEngine)
    {
    Q_未使用(发动机)
    Q_未使用(脚本引擎)
    静态MyItem*item=nullptr;
    如果(!项)
    item=新的MyItem();
    退货项目;
    }
    int main(int argc,char*argv[])
    {
    QApplication应用程序(argc、argv);
    qmlRegisterSingletonType(“Qt.MyTest”,1,0,“MyItem”,my_singleton_提供程序);
    qqmlaplicationengine;
    engine.load(QUrl(QStringLiteral(“qrc:/main.qml”));
    返回app.exec();
    }
    
    所以要测试它的QML文件:

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

    项目{
    id:testItem
    函数func1()
    {
    log(“func1正在执行…”)
    MyItem.someAsyncFuncFinished.connect(func2);
    MyItem.someAsyncFunc();
    }
    函数func2()
    {
    log(“func2正在执行…”)
    }
    Component.onCompleted:func1();
    }
    
    2。将JS函数传递给C++:

    项目{
    id:testItem
    函数func1()
    {
    log(“func1正在执行…”)
    MyItem.someAnotherAsyncFunc(func2);
    }
    函数func2()
    {
    log(“func2正在执行…”)
    }
    Component.onCompleted:func1();
    }
    
    那么你的问题是什么?您是否已经根据您提供的代码在
    func1()
    之后执行了
    func2()
    ?我建议依次调用它们。比如像代码。是什么让你认为它们没有一个接一个地执行?我认为你的问题是,
    fun1()
    只启动在另一个线程中异步执行的方法
    ImageReader.magic(照片)
    。所以你的问题应该是:在
    ImageReader
    用他的魔法完成后,我如何开始
    fun2()
    。因为
    fun1()
    可能在此之前完成。因此,
    fun2()
    fun1()
    完成后立即执行,但在
    ImageReader.magic(photo)
    完成之前执行。或者按照和其他QML组件的模式,在
    ImageReader
    中包含属性
    status
    。这与属性
    statusChanged
    一起出现,据我所知
    QQuickImageProvider
    不是从
    QObject
    继承的,因此使用信号需要在继承中进行更改。但我同意@derM,这是一个很好的方法来做你想做的事情。另一种方法是将指针传递给C++对象(在您的情况下为IVIDERADER)。请参阅问题的答案以了解更多信息。谢谢。但它仍然不起作用<代码>ImageReader.magic(照片)是通过继承QIMAGE提供程序在C++中编写的,它需要较长的时间来处理图像并返回到QML。