我在QML中有两个javascript函数fun1
,fun2
,并希望在另一个(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项显示它。
答案 0 :(得分:5)
好的,我只想总结一下那些会搜索相同解决方案的人。
至少有两种方法可以做到:
测试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)
基本上,你有两种方法可以解决这个问题
我不推荐第二种方法,特别是在声明性环境中,所以让我们进一步研究选项一。
对于C ++和QML / JavaScript之间的通知,您基本上还有两个选项
QObject
信号机制 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());