Qt 使用QJSValue调用时崩溃
当我调用Qt 使用QJSValue调用时崩溃,qt,qml,Qt,Qml,当我调用QJSValues调用函数时,JavaScript函数经常崩溃 我有一个正在运行的线程,将QMetaObject invokeMethod作为QueuedConnection调用,而不是DirectConnection,以确保该方法将在主ui线程中调用。然后调用的此方法将触发QJSValueJavaScript函数。JavaScript函数修改QML中的一些UI元素。当UI元素没有修改时,我注意到没有崩溃 有什么我应该注意的问题吗 在用覆盆子PI3跑了大约10个小时后,它就崩溃了 1??
QJSValue
s调用函数时,JavaScript函数经常崩溃
我有一个正在运行的线程,将QMetaObject invokeMethod作为QueuedConnection
调用,而不是DirectConnection
,以确保该方法将在主ui线程中调用。然后调用的此方法将触发QJSValue
JavaScript函数。JavaScript函数修改QML中的一些UI元素。当UI元素没有修改时,我注意到没有崩溃
有什么我应该注意的问题吗
在用覆盆子PI3跑了大约10个小时后,它就崩溃了
1??2 QV4::Object::调用qv4object_p.h 372 0x765d5a8c
3 QJSValue::调用QJSValue.cpp 670 0x765d5a8c
4.0x70352fb8 这是第6章插件的修改代码 皮耶查特工人阶级
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);
}
}
这个问题我已经研究了好几个小时,终于解决了 首先。JS函数有一个类似于
context
的概念,您的回调使用label
,它是一个外部UI对象。
因此,当从C++调用时,JS引擎不知道什么是代码>标签< />代码,因为<代码>上下文< /代码>发生了更改。p>
您可以这样声明回调(将回调与根绑定):
第二个。如果修改回调中的UI属性,必须确保它在主循环中被调用。就像label.text=…
,您必须在主循环中执行此操作
您可以使用
QCoreApplication::postEvent
调用主循环中的QJSValue。我已经研究了几个小时这个问题,最后解决了它
首先。JS函数有一个类似于context
的概念,您的回调使用label
,它是一个外部UI对象。
因此,当从C++调用时,JS引擎不知道什么是代码>标签< />代码,因为<代码>上下文< /代码>发生了更改。p>
您可以这样声明回调(将回调与根绑定):
第二个。如果修改回调中的UI属性,必须确保它在主循环中被调用。就像label.text=…
,您必须在主循环中执行此操作
您可以使用
QCoreApplication::postEvent
调用主循环中的QJSValue。Holy moly您在这里做什么,重新开始我的朋友。从PyCARCC++中发出信号<代码>响应<代码>,然后简单地使用自动生成的QML信号处理程序<代码>响应:< /C> >执行一些JavaScript。一旦你认为你需要使用任何QJS类,你马上就会知道这种方法是错误的。我认为提供头文件也是有用的,即使它们很简单。它将允许我们编译和修改您的代码。代码基于QT饼图中的示例应用程序。我不想使用onResponse的原因是,有一个要求,可以在QML中注册一个javascript函数作为回调。不建议使用QJSValue,实际上没有Qt示例建议在用户代码中使用QJSValue。为什么不能从QML信号处理程序调用JS函数,例如onResponse?为您提供信号槽是为了避免回调函数。对invokeMethod
的调用调用PieChartWorker对象的responseInternal
,因此即使您使用的是队列连接,responseInternal
仍将在PieChartWorker线程中调用,response
方法和updateResponse
回调也是如此。如果您不相信,请在每个线程上设置objectName属性,并使用qDebug()打印出来,您将看到PieChartWorker中发生的一切都可能导致不稳定性Holy moly您在这里做什么,请重新开始我的朋友。从PyCARCC++中发出信号<代码>响应<代码>,然后简单地使用自动生成的QML信号处理程序<代码>响应:< /C> >执行一些JavaScript。一旦你认为你需要使用任何QJS类,你马上就会知道这种方法是错误的。我认为提供头文件也是有用的,即使它们很简单。它将允许我们编译和修改您的代码。代码基于QT饼图中的示例应用程序。我不想使用onResponse的原因是,有一个要求,可以在QML中注册一个javascript函数作为回调。不建议使用QJSValue,实际上没有Qt示例建议在用户代码中使用QJSValue。为什么不能从QML信号处理程序调用JS函数,例如onResponse?为您提供信号槽是为了避免回调函数。对invokeMethod
的调用调用PieChartWorker对象的responseInternal
,因此即使您使用的是队列连接,responseInternal
仍将在PieChartWorker线程中调用,response
方法和updateResponse
回调也是如此。如果您不相信这一点,请在每个线程上设置objectName属性,并使用qDebug()打印出来,您将看到PieChartWorker中发生的一切都可能导致不稳定
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
}
}
}
Item{
id: root
function reload() {
X.send(request, root.callback)
}
function callback(data) {
console.log(data, root)
}
}