好吧,我只想爲那些將要搜索相同解決方案的人進行總結。
至少有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();
}
那麼你的問題是什麼?你不是已經根據你提供的代碼在'func1()'之後執行'func2()'嗎? – folibis
我會建議一個接一個地打電話給他們。例如像代碼[這裏](http://stackoverflow.com/questions/42607709/javascript-waiting-in-qml)。是什麼讓你覺得他們不是一個接一個地被執行? – derM
我認爲你的問題是,'fun1()'只啓動在另一個線程中異步執行的ImageReader.magic(photo)方法。所以你的問題應該是:*在'ImageReader'完成他的魔法之後,我該如何開始'fun2()',因爲'fun1()'可能在此之前完成。所以'fun2()'在'fun1()'完成之後,'ImageReader.magic(photo)'完成之前執行。 – derM