Coercion to interface not working for context property



  • Hi,

    I have a property which is a pointer to an interface. I want to assign that property with an object which implements the interface. It works if the object is instantiated in qml. Is there some reason it shouldn't work if the object is provided through a context property?

    I can use the context property if the interface is changed to be a base class which inherits QObject.

    I have modified the Coercion example to highlight the problem. The original can be found "here":http://qt-project.org/doc/qt-4.8/declarative-cppextensions-referenceexamples-coercion.html.

    person.h
    Modified to make Person a regular purely virtual c++ interface. Boy and Girl now inherit QObject and Person.
    @class Person
    {
    public:
    virtual ~Person() {}

    virtual QString name() const = 0;
    virtual int shoeSize() const = 0;
    

    };

    Q_DECLARE_INTERFACE(Person, "examples.Coercion.Person/1.0");

    class Boy : public QObject, public Person
    {
    Q_OBJECT
    Q_INTERFACES(Person)
    Q_PROPERTY(QString name READ name WRITE setName)
    Q_PROPERTY(int shoeSize READ shoeSize WRITE setShoeSize)
    public:
    Boy(QObject * parent = 0);

    QString name() const;
    void setName(const QString &);
    
    int shoeSize() const;
    void setShoeSize(int);
    

    private:
    QString m_name;
    int m_shoeSize;
    };

    class Girl : public QObject, public Person
    {
    ...
    }
    @

    person.cpp
    Boy implements Person (Girl is the same but not shown here).
    @
    Boy::Boy(QObject *parent)
    : QObject(parent), m_shoeSize(0)
    {
    }
    QString Boy::name() const
    {
    return m_name;
    }
    void Boy::setName(const QString &n)
    {
    m_name = n;
    }
    int Boy::shoeSize() const
    {
    return m_shoeSize;
    }
    void Boy::setShoeSize(int s)
    {
    m_shoeSize = s;
    }
    @

    main.cpp
    Person is registered as an interface. A Boy instance is created and set as context property "bobby".
    @
    int main(int argc, char ** argv)
    {
    QCoreApplication app(argc, argv);

    qmlRegisterType<BirthdayParty>("People", 1,0, "BirthdayParty");
    qmlRegisterInterface<Person>("Person");
    
    qmlRegisterType<Boy>("People", 1,0, "Boy");
    qmlRegisterType<Girl>("People", 1,0, "Girl");
    
    Boy *bobby = new Boy();
    bobby->setName("Bob Jones");
    bobby->setShoeSize(12);
    
    QQmlEngine engine;
    engine.rootContext()->setContextProperty("bobby", bobby);
    QQmlComponent component(&engine, QUrl("qrc:example.qml"));
    BirthdayParty *party = qobject_cast<BirthdayParty *>(component.create());
    
    if (party && party->host()) {
        qWarning() << party->host()->name() << "is having a birthday!";
    
        if (dynamic_cast<Boy *>(party->host()))
            qWarning() << "He is inviting:";
        else
            qWarning() << "She is inviting:";
    
        for (int ii = 0; ii < party->guestCount(); ++ii)
            qWarning() << "   " << party->guest(ii)->name();
    } else {
        qWarning() << component.errors();
    }
    
    return 0;
    

    }
    @

    example.qml
    The existing code still works, host can be assigned to a qml instance of Boy, however, using the context property bobby results in: qrc:example.qml:46:11: Unable to assign Boy to Person*.

    @
    BirthdayParty {
    /* Doesn't work */
    //host: bobby

    /*  Does work       */
    host: Boy {
        name: "Bob Jones"
        shoeSize: 12
    }
    
    guests: [
        Boy { name: "Leo Hodges" },
        Boy { name: "Jack Smith" },
        Girl { name: "Anne Brown" }
    ]
    

    }
    @

    I can't find any documentation which explains why this wouldn't work. I thought that the meta object system should be able to coerce bobby into a Person*. Any one have any ideas?


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.