J'ai un MasterController QObject avec une méthode Q_INVOKABLE qui renvoie une référence const à un objet de MyType, un autre type dérivé de QObject. J'enregistre les deux dans main(). J'instancie un MasterController et l'ajoute également au contexte racine dans main. Dans mon QML, j'importe le module enregistré contenant les deux types QObject dérivés. Dans le QML, je peux appeler la méthode MasterController. Je le vois entrer dans le débogueur. Mais, lorsque l'exécution revient au code QML, la variable renvoyée est « undefined ». Donc, je ne peux lire aucune de ses propriétés. J'ai lu la question et les réponses pour la méthode Q_INVOKABLE renvoyant un type C++ personnalisé. Mais, cela ne m'a pas donné assez d'informations pour bien faire les choses.

MonType.h

#ifndef MYTYPE_H
#define MYTYPE_H

#include <QObject>

#include <testqt-lib_global.h>

namespace testqt {
namespace models {

class TESTQTLIB_EXPORT MyType : public QObject
{
    Q_OBJECT
    Q_PROPERTY( int ui_height READ height )
    Q_PROPERTY( int ui_width READ width )

public:
    explicit MyType(QObject *parent = nullptr);

    int height() const;
    int width() const;

private:
    int _height = 2;
    int _width = 3;
};

} // namespace models
} // namespace testqt

#endif // MYTTYPE_H

MonType.cpp

#include "mytype.h"

namespace testqt {
namespace models {

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

int MyType::height() const
{
    return _height;
}

int MyType::width() const
{
    return _width;
}

} // namespace models
} // namespace testqt

MasterController.h

#ifndef MASTERCONTROLLER_H
#define MASTERCONTROLLER_H

#include <QObject>

#include "testqt-lib_global.h"
#include "mytype.h"

namespace testqt {
namespace controllers {

class TESTQTLIB_EXPORT MasterController : public QObject
{
    Q_OBJECT

public:
    explicit MasterController(QObject *parent = nullptr);
    ~MasterController();

    Q_INVOKABLE const models::MyType& getData() const;

private:
    models::MyType _myData;
};

} // namespace controllers
} // namespace testqt

#endif // MASTERCONTROLLER_H

MasterController.cpp

#include "mastercontroller.h"

namespace testqt {
namespace controllers {

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

MasterController::~MasterController()
{
}

const models::MyType& MasterController::getData() const
{
    return _myData;
}

} // namespace controllers
} // namespace testqt

Main.cpp (principalement passe-partout)

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>

#include "mastercontroller.h"
#include "mytype.h"

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QGuiApplication app(argc, argv);

    qmlRegisterType<testqt::models::MyType>("TestQt", 1, 0, "MyType");
    qmlRegisterType<testqt::controllers::MasterController>("TestQt", 1, 0, "MasterController");

    QQmlApplicationEngine engine;

    testqt::controllers::MasterController masterController;
    engine.rootContext()->setContextProperty("masterController", &masterController);

    const QUrl url(QStringLiteral("qrc:/main.qml"));
    QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                     &app, [url](QObject *obj, const QUrl &objUrl) {
        if (!obj && url == objUrl)
            QCoreApplication::exit(-1);
    }, Qt::QueuedConnection);
    engine.load(url);

    return app.exec();
}

Main.qml

import QtQuick 2.11
import QtQuick.Window 2.11
import TestQt 1.0

Window {
    width: 640
    height: 480
    visible: true
    title: qsTr("testqt")

    Text {
        id: heightLabel
        anchors.top: parent.top
        anchors.left: parent.left
        text: "height unknown"
    }

    Text {
        id: widthLabel
        anchors.top: heightLabel.bottom
        anchors.left: parent.left
        text: "width unknown"
    }

    Component.onCompleted: {
        var data = masterController.getData();
        if (data)  // data always undefined
        {
            heightLabel.text = data.height.toString();
            widthLabel.text = data.width.toString();
        }
    }
}
1
Josh 16 nov. 2020 à 21:43

1 réponse

Meilleure réponse

Les QObjects ne sont pas copiables donc vous ne pouvez pas passer la référence d'un QObject mais plutôt le pointeur :

Q_INVOKABLE QObject* getData();
QObject *MasterController::getData()
{
    return &_myData;
}
1
eyllanesc 17 nov. 2020 à 03:20