QtScript не может вызывать функцию с типом аргумента QString &

Я получил ошибку ниже

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

при выполнении моей программы Qt test.exe для вызова файла javascript haha.js. То, что я пытался сделать, это вернуть значение («результат») из «void sayHello (const QString & name, QString & result);» в джаваскрипте. Похоже, QtScript понимает (const QString &), но не может понять (QString &). Есть идеи, что я сделал не так?

хаха.js

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

программа Qt состоит: haha.h, haha.cpp, main.cpp

ха-ха.ч

#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

хаха.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();
}

person zhongzhu    schedule 02.07.2013    source источник


Ответы (4)


Похоже, что ваш исходный вопрос имеет 2 подвопроса:

Q1. Как избежать вышеуказанной ошибки времени выполнения?

Q2. Как вернуть несколько данных из С++ в QML?

А1. Похоже, что QML плохо распознает ссылочный символ C++ &, и это не имеет значения, используете ли вы const или нет. Итак, если вы используете следующую версию:

void sayHelloV2(const QString name, QString result);

ошибка времени выполнения исчезнет. Точнее, QML позволяет первым аргументом быть ссылкой на C++, поэтому следующая версия также может избежать ошибки времени выполнения:

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

Это загадка и для меня. Возможно, разработчики фреймворка Qt смогут объяснить нам, почему.

А2. Если вы хотите, чтобы несколько данных возвращались из C++ в QML, одним из решений является использование QVariantMap в качестве типа возвращаемого значения функции, как показано в следующей версии:

QVariantMap sayHelloV4(const QString name, QString result);

Внутри возвращаемого значения C++ вы можете вставить столько данных, сколько необходимо. (имя, результат и т.д.). Но ваш QML-код должен обработать возвращаемое значение, чтобы получить нужные вам данные.

person jonathanzh    schedule 08.04.2016

Ваш второй аргумент имеет тип QString&, но он должен быть const QString&.

person Pavel Strakhov    schedule 02.07.2013
comment
для второго аргумента я намеревался использовать QString и чтобы я мог передать QString и получить результат от вызова void sayHello(const QString &name, QString &result) - person zhongzhu; 02.07.2013
comment
Используйте QString sayHello(const QString& name), чтобы вернуть значение из функции. - person Pavel Strakhov; 02.07.2013
comment
но я хочу, чтобы sayHello() возвращал как код ошибки, так и значение. Есть ли способ заставить (QString &) работать? - person zhongzhu; 02.07.2013

Я не эксперт по JavaScript. Но после того, как Google «вернет значение через параметры в javascript» и «вернет несколько значений в javascript». Но сам стандарт не нашел.

Я думаю, что ваш способ получить возвращаемое значение в параметре невозможен. Тогда QString& здесь не имеет значения.

Надеюсь, что другие могут научить или исправить меня в этой теме, спасибо.

person Liang Qi    schedule 02.07.2013
comment
Я разместил еще один вопрос о том, как вернуть значение из JavaScript, по адресу stackoverflow.com/questions/17438475/ , они дали мне 2 способа решить мою проблему. Подробности можно проверить там. - person zhongzhu; 03.07.2013

Преобразование данных между js и типом данных Qt выполняется QScriptValue, в основном это означает, что QString в слоте не является строкой js, которую вы передали.

Передача ссылки не может творить чудеса, просто подумайте о другом способе.

Например, вы можете добавить функцию, которая возвращает последнюю ошибку.

person csslayer    schedule 06.07.2013
comment
то есть вы имеете в виду, что нет способа вернуть значение из параметра функции? - person zhongzhu; 08.07.2013