3

destroyedQtスクリプトからQObjectのシグナルに正しく接続するには?

平均的な信号のように接続すると、機能しません。オブジェクトを削除したことと、他の QObjects がシグナルを受信したことをテストしましたが、それに接続したスクリプト関数は呼び出されません。

以下は、テストに使用しているサンプルです。最も重要な部分は次の行です。

_engine.evaluate("obj.destroyed.connect(function() { debug(\"obj destroyed\") })");

objが破棄されたときにその関数を呼び出すことを期待しています。destroyed以下のコードは、ループがすでに開始されているときにオブジェクトが削除されることを保証し、オブジェクトが別の QObject にシグナルを送信したこともテストします。私が修正したいのは、スクリプトがシグナルのdebug("obj destroyed")後にスクリプト関数を呼び出すことです。destroyed

ScriptTester.h:

#ifndef SCRIPTTESTER_H
#define SCRIPTTESTER_H

#include <QtScript>
#include <QtCore>

class ScriptTester: public QObject {
    Q_OBJECT

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

private slots:
    void signalTest();
    void boo();

private:
    QScriptEngine _engine;
};

#endif // SCRIPTTESTER_H

ScriptTester.cpp:

#include "ScriptTester.h"

static QScriptValue scriptDebug(QScriptContext *context, QScriptEngine *engine) {
    Q_UNUSED(engine);
    if (context->argumentCount() >= 1) {
        QString msg = context->argument(0).toString();
        for (int i = 1; i < context->argumentCount(); ++i) {
            msg = msg.arg(context->argument(i).toString());
        }
        qDebug() << msg;
    }
    return QScriptValue();
}

ScriptTester::ScriptTester(QObject *parent) :
    QObject(parent)
{
    QTimer::singleShot(0, Qt::CoarseTimer, this, SLOT(signalTest()));
    _engine.globalObject().setProperty("debug", _engine.newFunction(scriptDebug, 1));
}

void ScriptTester::signalTest() {
    QObject *obj = new QObject(this);
    _engine.globalObject().setProperty("obj", _engine.newQObject(obj));
    _engine.evaluate("obj.destroyed.connect(function() { debug(\"obj destroyed\") })");
    if (_engine.hasUncaughtException()) {
        qDebug() << "Exception:" << _engine.uncaughtException().toString();
    }
    connect(obj, SIGNAL(destroyed()), this, SLOT(boo()));

    QTimer *timer = new QTimer;
    _engine.globalObject().setProperty("timer", _engine.newQObject(timer));
    _engine.evaluate("timer.timeout.connect(function() { debug(\"timer timeout\"); obj.deleteLater(); })");
    if (_engine.hasUncaughtException()) {
        qDebug() << "Exception:" << _engine.uncaughtException().toString();
    }

    timer->setSingleShot(true);
    timer->start(100);
}

void ScriptTester::boo() {
    qDebug() << "was destroyed!";
}

destroyed最初に C++ コードに渡し、次に手動で、またはそのスクリプトを通知するシグナルによって渡すようなハックはしたくないことに注意してください。スクリプトで完全に実行される実装を探しています。

4

0 に答える 0