QJSEngine add custom object



  • Hi,

    I am trying to use a script to plot a graph in my program.
    I am using QCustomPlot and it works fine if used in my C++ code.
    However, if I pass the QCustomPlot to the QJSEngine like this:

    QJSEngine myEngine;
    QCustomPlot *graph = new QCustomPlot;
    QJSValue scriptgraph = myEngine.newQObject(graph);
    myEngine.globalObject().setProperty("graph",scriptgraph);
    

    And my script looking like this:

    graph.addGraph();
    graph.xAxis.setLabel("TESTX");
    graph.yAxis.setLabel("TESTY");
    graph.replot();
    

    The QJSEngine will throw the following error:
    result: 1 : "ReferenceError: addGraph is not defined"

    Which makes me think that the object is passes but not the classes it has. Am I missing something here?

    Thanks!



  • @TheHawk

    Hi,

    You need to show your QCustomPlot class. Did you add the Q_INVOKABLE macro in front of your addGraph() function?

    Greetings,

    t3685



  • @t3685

    The QCustomPlot is from internet. And no, I did not add Q_Invokable to the functions of QCustomPlot. I can try and see if this fixes the error. Thanks!

    Edit: tried Q_INVOKABLE QCPGraph *addGraph(QCPAxis *keyAxis=0, QCPAxis *valueAxis=0); without succes.



  • @TheHawk

    Hi,

    What error are you getting? Did you rerun qmake to regenerate the moc_*.cpp files?

    Greetings,

    t3685



  • @t3685
    Hi,

    I am getting: result: 1 : "ReferenceError: addGraph is not defined" with my script looking like:

    	graph.addGraph();
    	graph.xAxis.setLabel("TESTX");
    	graph.yAxis.setLabel("TESTY");
    	graph.replot();
    

    and wrapping the graph like this:

        QCustomPlot *graph = new QCustomPlot;
        ui->verticalLayout->addWidget(graph);
        QJSValue scriptgraph = myEngine.newQObject(graph);
        myEngine.globalObject().setProperty("graph",scriptgraph);
    

    And yes, I cleaned, reran Qmake and even rebuild everything but without succes.

    Am I running into a limitation of QJSEngine? If so, what would be the wisest thing for me to do? I would really like to access objects like the above, if that is not possible, would QTQuick with QML be anything for me? If I read this it looks like that what I am trying to achieve is relatively simple in QML with QtQuick. However, I do not have QtQuick installed at the moment so I would have to rewrite all my existing code to use the import "script.js" as scipt function, correct? If not, how would this be done in my Qt Creator project?

    Thanks! :)



  • @TheHawk

    Hi,

    How are you invoking your script? As in how are you calling "script.js". Are you calling it using "myEngine"? If yes, can you show that code?

    Greetings,

    t3685



  • @t3685
    Hi,

    I am calling it like this:

        QString fileName = "customlogic.qs";
        QFile scriptFile(fileName);
        if (!scriptFile.open(QIODevice::ReadOnly))
        {
        }// handle error
    
        QTextStream stream(&scriptFile);
        QString contents = stream.readAll();
        scriptFile.close();
        QJSValue result = myEngine.evaluate(contents, fileName);
        if (result.isError())
        {
            qDebug() << "result: " << result.property("lineNumber").toInt() << ":" << result.toString();
        }
    
    

    thanks!



  • @TheHawk

    Have you tried giving argument to addGraph()? I don't remember whether the default argument translate well to javascript. If that still doesn't work, you can try to make add a dummy QObject class with Q_INVOKABLE functions to your engine to see if the problem is in your code or some possible interaction with QCustomPlot