1

I got below error

"TypeError: cannot call sayHello(): argument 2 has unknown type `QString&' (register the type with qScriptRegisterMetaType())"

when execute my Qt program test.exe to call a javascrip file haha.js. What I was trying to do is to return a value ("result") from "void sayHello(const QString &name, QString &result);" in javascript. Looks like QtScript understands (const QString &) but can't understand (QString &). Any idea what I did wrong?

haha.js

h = new Haha();
result = "";
h.sayHello("henry", result);
result;

the Qt program consists: haha.h, haha.cpp, main.cpp

haha.h

#ifndef HAHA_H
#define HAHA_H

#include <QObject>

class Haha : public QObject
{
    Q_OBJECT

public:
    explicit Haha(QObject *parent = 0);

public slots:
    void sayHello(const QString &name, QString &result);
};

#endif // HAHA_H

haha.cpp

#include "haha.h"

Haha::Haha(QObject *parent) :
    QObject(parent)
{
}

void Haha::sayHello(const QString &name, QString &result)
{
    result = "Hello " + name;
}

main.cpp

#include <QtCore/QCoreApplication>
#include <QtDebug>
#include <QtScript>

#include "haha.h"

Q_SCRIPT_DECLARE_QMETAOBJECT(Haha, QObject*)

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QScriptEngine engine;
    QScriptValue HahaClass = engine.scriptValueFromQMetaObject<Haha>();
    engine.globalObject().setProperty("Haha", HahaClass);

    QString fileName = "haha.js";
    QFile scriptFile(fileName);
    if (!scriptFile.open(QIODevice::ReadOnly)) {
        return -1;
    }
    QTextStream b(&scriptFile);
    QString contents = b.readAll();
    scriptFile.close();

    QScriptValue result = engine.evaluate(contents, fileName);
    qDebug()<<result.toString();

    return a.exec();
}
zhongzhu
  • 307
  • 2
  • 4
  • 14

4 Answers4

1

It appears that your original question has 2 sub-questions:

Q1. How to avoid the above runtime error?

Q2. How to return multiple data from C++ to QML?

A1. It appears that QML does not recognize well C++ reference symbol &, and this does not matter whether you use const or not. So if you use the following version:

void sayHelloV2(const QString name, QString result);

the runtime error will go away. More precisely, QML does allow the first argument to be a C++ reference, so the following version can also avoid the runtime error:

void sayHelloV3(const QString &name, QString result);

This is a mystery to me as well. Maybe Qt framework developers can explain us why.

A2. If you want multiple data to be returned from C++ to QML, one solution is to use QVariantMap as the function's return type, as shown in the following version:

QVariantMap sayHelloV4(const QString name, QString result);

Inside your C++ return value, you can insert as many data as needed. (name, result, etc.). But your QML code has to post-process the return value to get the data you need.

jonathanzh
  • 1,346
  • 15
  • 21
0

Your second argument has QString& type, but it should be const QString&.

Pavel Strakhov
  • 39,123
  • 5
  • 88
  • 127
  • for the 2nd argument, I intended to use "QString &" so that I can pass in a QString and get result from calling "void sayHello(const QString &name, QString &result)" – zhongzhu Jul 02 '13 at 08:23
  • Use `QString sayHello(const QString& name)` to return a value from the function. – Pavel Strakhov Jul 02 '13 at 08:31
  • but I do want the sayHello() to return both an error code and a value. Is there a way to make (QString &) work? – zhongzhu Jul 02 '13 at 09:21
0

I am not an expert on JavaScript. But after google "return value through parameters in javascript" and "return multiple values in javascript". But I didn't find the standard myself.

I think your way to have return value in parameter is impossible. Then QString& is no meaning here.

Hope others could teach or correct me on this topic, thanks.

Liang Qi
  • 141
  • 1
  • 5
  • I've posted another question to ask about how to return value from JavaScript at http://stackoverflow.com/questions/17438475/possible-to-return-a-value-from-javascript-function-parameter , they gave me 2 ways to solve my problem. You can check the details there. – zhongzhu Jul 03 '13 at 04:34
0

The data conversion between js and Qt data type is done by QScriptValue, basically this means the QString in the slot is not the js string you passed in.

Passing a reference cannot do the magic, just think about some other way.

For example, you can add a function that returns the last error.

csslayer
  • 317
  • 2
  • 9