Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Qt 使用QJSValue调用时崩溃_Qt_Qml - Fatal编程技术网

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)
    }
}