我需要从QML UI控制慢速I / O操作。 I / O接口是C ++。基本上,当用户按下按钮时,我需要发送消息并从设备获得响应。我希望用户在等待响应时能够做其他事情。 WorkerScript似乎是实现这一目标的最简单方法,但是如何将我的C ++接口放入脚本中,因为正常的QDeclarativeContext没有传入线程?有没有办法将C ++导入QML的javascript?我甚至不需要在主线程中维护C ++上下文,我可以完全生活在工作者中并且只是来回传递消息。
编辑:
澄清:@dtech的答案满足了我目前的需求,但我仍然想知道这个问题的答案:是否有可能将C ++(即使没有状态)转换为WorkerScript。
答案 0 :(得分:1)
如果您可以选择将QObject
放入专用线程,在不阻塞主线程的情况下执行代码,并且不同步地来回传递和交付结果,为什么会这样做呢?
您不需要WorkerScript
,也不是它的预期用途。既然您的代码仍然是C ++,那么您只需要QThread
和QObject
。
这是一个简单的例子:
class Worker : public QObject {
Q_OBJECT
public slots:
void doWork() {
int i = 0;
while (i < 100) {
result(i++);
std::this_thread::sleep_for(std::chrono::milliseconds(500));
}
}
signals:
void result(int r);
};
class Controller : public QObject {
Q_OBJECT
public:
Controller() {
w = new Worker;
t = new QThread;
w->moveToThread(t);
connect(this, SIGNAL(start()), w, SLOT(doWork()));
connect(w, SIGNAL(result(int)), this, SIGNAL(result(int)));
t->start();
}
private:
Worker * w;
QThread * t;
signals:
void start();
void result(int r);
};
// in main.cpp
Controller cw;
engine.rootContext()->setContextProperty("Work", &cw);
engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); // load main qml
// QML
Column {
Button {
id: start
onClicked: Work.start()
}
Text {
id: res
}
}
Connections {
target: Work
onResult: res.text = r
}
这是一个简单的阻塞工作程序,它将阻塞其线程约50秒,但仍然能够发出将在QML端更新的结果,同时保持GUI线程空闲。请注意,一旦调用了工作函数,就无法以任何方式中断,暂停或控制它,如果需要,则必须实现non-blocking worker。也不需要C ++控制器作为QML和“线程对象”之间的中介,因为看起来QML不能直接与这些对象相处。