1

I'm currently create an apps in Meego using QML and JS on most of the part. and now I stumbled upon a problem.

From javascript I want to call a C++ function to read text file, parse it, and then return an array of the parsing result. so I create a Q_INVOKABLE function called parse() and call it through javascript

function parse() {
    var myArray = new Array();
    myArray = parser.parse("/home/user/MyDocs/angklungtext.txt")
    if(myArray === undefined){
        console.log("null found");
    }

    for(var i = 0; i < myArray.length; i++){
        console.log(myArray[i][0] + "," + myArray[i][1])
    }
}

and here is the parse function in C++

QVariantList* QMLParser::parse(QString filename)
{
    qDebug() << "start debugging";

    qDebug() << filename;
    qDebug() << QDir::currentPath();
    QDir dir;
    qDebug()<< dir.absoluteFilePath(filename);

    QFile file(filename);
    if(!file.exists())
    {
        qDebug() << "File: " << file.fileName() << "tidak ditemukan";
        return NULL;
    }

    if(!file.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        qDebug() << "Tidak dapat membuka file" << file.fileName() << "untuk ditulis";
        return NULL;
    }

    QTextStream stream(&file);

    QVariantList* myList = new QList<QVariant>;

    while(!stream.atEnd())
    {
        QString line = stream.readLine();
        qDebug() << line.trimmed();
        QStringList lineList = line.split(":");
        myList->append(lineList);
    }

    file.close();

    return myList;
}

sadly. when I try to run it it giving a result like this

start debugging 
"/home/user/MyDocs/angklungtext.txt" 
"/home/developer" 
"/home/user/MyDocs/angklungtext.txt" 
"1:1000" 
"4:2000" 
"5:3000" 
"2:4000"
null found
file:///opt/memoryreader/qml/memoryreader/myjs.js:8: TypeError: Result of expression 'myArray' [undefined] is not an object.

looks like the C++ parse function successfully parsing the file. it can read it and it can save it into the QVariantList. but after it return the result into javascript myArray still [undefined]. is there something wrong with the conversion?

Fugogugo
  • 4,460
  • 10
  • 36
  • 50

2 Answers2

2

Just simplify the C++ side like this :

QVariant QMLParser::parse(QString filename)
{
    QStringList myList;

    qDebug() << "start debugging";

    qDebug() << filename;
    qDebug() << QDir::currentPath();
    QDir dir;
    qDebug() << dir.absoluteFilePath(filename);

    QFile file(filename);
    if(!file.exists()) {
        qDebug() << "File: " << file.fileName() << "tidak ditemukan";
        return NULL;
    }

    if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        qDebug() << "Tidak dapat membuka file" << file.fileName() << "untuk ditulis";
        return NULL;
    }

    QTextStream stream(&file);
    while(!stream.atEnd()) {
        QString line = stream.readLine();
        qDebug() << line.trimmed();
        myList << line.trimmed().split(":");
    }

    file.close();

    return QVariant::fromValue(myList);
}

And it should work !

Just remember, QML must see a QVariant, even if a QList is wrapped inside it, and Qt is able to convert most of its base types to QVariant using QVariant::fromValue(T) so use it extensively.

Oh and BTW a QVariant is reference not pointer.

TheBootroo
  • 7,408
  • 2
  • 31
  • 43
0

Haven't done this myself, so I'm just thinking out loud. But I note that you're returning a pointer to a QVariantList...which looks suspect. (Also: if you new, then who would do the delete?)

Have you tried returning it by value?

  • if i returned it by value, then the return NULL; on some conditional branch there can't be done – Fugogugo Oct 20 '11 at 10:32
  • Well, how would you differentiate between returning null and undefined then? As I say, I haven't really used QtScript, but I thought that rather than returning C++ NULLs and the like from these functions one was supposed to be using things like http://doc.qt.nokia.com/latest/qscriptvalue.html ... depends on what Q_INVOKABLE does but I'd be surprised if it does what you think. – HostileFork says dont trust SE Oct 20 '11 at 10:40
  • I'd say, return a QVariant. This can be null if an error is encountered and can also contain the QVariantList (by value) if successful. The JS part should handle the conversion appropriately IIRC. – Steffen Oct 20 '11 at 15:42
  • Steffen is right, you need to return QVariants by value (or you return QObjects as pointers). – blakharaz Oct 20 '11 at 20:22