当我调用QJSValue
的调用函数时,我的JavaScript函数经常崩溃。
我有一个正在运行的线程,将QMetaObject invokeMethod调用为QueuedConnection
而不是DirectConnection
,以确保在主ui线程中调用该方法。然后调用的此方法将随后触发QJSValue
JavaScript函数。 JavaScript函数修改QML中的一些UI元素。当没有对UI元素进行修改时,我注意到没有崩溃。
有什么问题需要注意吗?
在Raspberry PI3上运行大约10小时后崩溃。
1 ?? 2 QV4 :: Object :: call qv4object_p.h 372 0x765d5a8c
3 QJSValue :: call qjsvalue.cpp 670 0x765d5a8c
4 ?? 0x70352fb8
这是第6章插件修改后的代码
PieChartWorker类
PieChartWorker::PieChartWorker(QObject *parent):
QThread(parent)
{
}
void PieChartWorker::run()
{
QString text;
while(1) {
QString textb = text.sprintf("The answer to the meaning of life is %i", std::rand()%100);
QMetaObject::invokeMethod(this,
"responseInternal",
Qt::QueuedConnection,
Q_ARG(QString, QString::fromLocal8Bit("hello")),
Q_ARG(QByteArray, textb.toLocal8Bit()));
QThread::msleep(50);
}
}
void PieChartWorker::responseInternal(const QString question, const QByteArray& answer)
{
emit response(question, answer, callback);
}
void PieChartWorker::registerCallback(const QJSValue callback)
{
this->callback = callback;
start();
}
PieChart课程
PieChart::PieChart(QQuickItem *parent)
: QQuickItem(parent)
{
PieChartWorker* worker = new PieChartWorker();
worker->moveToThread(&m_thread);
connect(&m_thread, &QThread::finished, worker, &QObject::deleteLater);
connect(this, &PieChart::registerCallback, worker, &PieChartWorker::registerCallback);
connect(worker, &PieChartWorker::response, this, &PieChart::response);
m_thread.start();
}
void PieChart::response(const QString question, const QByteArray& answer, QJSValue callback)
{
if (callback.isCallable()) {
QJSValueList args;
args << question;
args << QString::fromLocal8Bit(answer);
callback.call(args);
}
}
app.qml
import QtQuick 2.0
import Charts 1.0
Item {
width: 300; height: 200
Text {
id: label
text: "hello"
x:100; y:100
color: 'black'
}
PieChart {
anchors.center: parent
width: 100; height: 100
Component.onCompleted: {
registerCallback(updateResult)
}
function updateResult(question, answer) {
console.log(question)
console.log(answer)
label.text = answer
}
}
}
答案 0 :(得分:0)
我已经在这个问题上工作了几个小时,最后,我解决了它。
首先。 JS函数有一个像context
这样的概念,你的回调使用label
,它是一个外部UI对象。
因此,当从C ++调用它时,JS引擎不知道label
是什么,因为context
已更改。
你可以像这样声明回调(用root绑定回调):
Item{
id: root
function reload() {
X.send(request, root.callback)
}
function callback(data) {
console.log(data, root)
}
}
其次。如果修改回调中的UI属性,则必须确保在主循环中调用它。像label.text=...
一样,你必须在主循环中完成。
您可以使用QCoreApplication::postEvent
在主循环中调用QJSValue。