PDA

View Full Version : QT Integrating C++ and Javascript



bmn
7th August 2011, 15:57
I'm currently developing a game (class requirement) similar to Are you Smarter than a 5th grader.

Seeing this, I should be able to retrieve the questions from a .txt file which I can do. The problem is that I want to send the values that I got from the .txt file to my javascript for processing. How do I do this?

Currently, I can get and save the questions from the text file using a QList<QString>. Although I don't know how to send these to Javascript. Based from research, I found out that you can use the QMetaObject::invokeMethod (here's the link where I found it http://doc.qt.nokia.com/4.7-snapshot/qtbinding.html) although I'm not sure how to integrate it with my QList.

I need help! :( Thanks!

wysota
9th August 2011, 10:33
How are you calling the scripts? Usually you'd just call QScriptEngine::evaluate() to trigger a script and possibly earlier expose some data to the script by setting some properties of either the global object of the script engine or the activation object of the script context.

bmn
9th August 2011, 12:14
I stumbled upon this while researching about QT: http://doc.qt.nokia.com/4.7-snapshot/qtbinding.html#javascript-arrays-and-objects


JavaScript arrays and objects
There is built-in support for automatic type conversion between QVariantList and JavaScript arrays, and QVariantMap and JavaScript objects.
For example, the function defined in QML below left expects two arguments, an array and an object, and prints their contents using the standard JavaScript syntax for array and object item access. The C++ code below right calls this function, passing a QVariantList and a QVariantMap, which are automatically converted to JavaScript array and object values, respectively:


// MyItem.qml
Item {
function readValues(anArray, anObject) {
for (var i=0; i<anArray.length; i++)
console.log("Array item:", anArray[i])

for (var prop in anObject) {
console.log("Object item:", prop, "=", anObject[prop])
}
}
}
// C++
QDeclarativeView view(QUrl::fromLocalFile("MyItem.qml"));

QVariantList list;
list << 10 << Qt::green << "bottles";

QVariantMap map;
map.insert("language", "QML");
map.insert("released", QDate(2010, 9, 21));

QMetaObject::invokeMethod(view.rootObject(), "readValues",
Q_ARG(QVariant, QVariant::fromValue(list)),
Q_ARG(QVariant, QVariant::fromValue(map)));


I tried to integrate this to my application. Although, instead of using QVariantList, I used a QStringList to retrieve values from my text file.



QStringList line;
...

QTextStream in(&inputFile);

while ( !in.atEnd() )
{
QString str = in.readLine();
//qDebug() << "message: " << str;
line.append(str);

}



Afterwards, I used the QMetaObject thing to pass the QStringList to my javascript function.



QMetaObject::invokeMethod(view.rootObject(), "readValues",
Q_ARG(QVariant, QVariant::fromValue(line)));

//WHERE readValues is my Javascript function


It works. And it reads and displays the retrieved values when I use console.log() in my .qml file. HOWEVER, whenever this it executed, I get a TypeError: file:///C:/Users/MYCOMP/Qt/Projectproj-build-desktop/qml/Projectproj/main.qml:65: TypeError: Result of expression 'anArray' [undefined] is not an object.

How come?

wysota
9th August 2011, 12:34
Are you using QML because you want to use QML or because the snippet you found uses QML? Because what you are trying to do right now yields little sense.

bmn
9th August 2011, 12:39
I have little knowledge regarding C++ (or C itself) although I know how to program in Java. I'm required by my professor to come up with an application using the QT platform and that is why I'm using this kind of approach.

I've read tutorials regarding QML and by seeing these tutorials, it is possible to create a simple game with the use of only QML and Javascript. The reason why I'm using a bit of C++ is because of the fact that I have to retrieve data from the text file (according to my professor :( ).

wysota
9th August 2011, 12:59
But why are you calling javascript code from C++ code? Shouldn't it be the other way round?

bmn
9th August 2011, 13:09
The only reason why I utilized C++ is just to retrieve values from the text file because based from research, Javascript isn't allowed to do that. After retrieving the lines from my text file, what I plan to do is let the Javascript handle the logic.

The only way I saw how this would be possible is if I used the QMetaObject thing that I saw in the QT documentation.

If what you're saying is that I should call a C++ function using Javascript, then my answer to that is I have no clue on how to do it. :(

EDIT:

If ever you can suggest anything easier to do besides what I've tried, I would really appreciate it. :)

wysota
9th August 2011, 13:39
You clearly have issues with designing the program. If your game is driven by javascript then the whole control is also in hands of javascript. The C++ code is only required to retrieve some data so when the right time comes you only need to call a C++ function and when it returns with the data you need, simply use the data. So the real task is to expose a C++ function/method to QML environment and the docs have examples of doing that.

bmn
9th August 2011, 13:43
I will try that. Thank you.

The reason why I structured mine in such a manner is that once the application is opened, I want all lines of the text file automatically retrieved by the C++ then processed by the Javascript.

I will read about it on the QT site and post here again.

EDIT:

Seeing that my poorly constucted method works, I would, for now, just want to know why I'm receiving a TypeError such as this whenever I try to manipulate the array (formerly the QStringList from the .cpp file) which contains the data from the text file that was passed to the javascript function using the QMetaObject method.
TypeError: file:///C:/Users/MYCOMP/Qt/Projectproj-build-desktop/qml/Projectproj/main.qml:65: TypeError: Result of expression 'anArray' [undefined] is not an object.

wysota
9th August 2011, 14:19
No idea, I don't really want to analyze code that's inherently broken. Apparently you're accessing a non-object as an object.