Casting signaled QObjects from C++ code



  • I have noticed that QML behaves differently when these objects are passed to the script as a signal. I have added to the previous code example that reproduces this.

    The update adds a singleShot QTimer that passed the object1 twice to the script. Once declared class and the second as a QObject.

    When passed as a class it is casted as a QVariant and I will not have access to any properties or slots.

    When passed as a QObject I will have access to properties but is also casted differently then when it is passed using the doSomething() function. (Clicking anywhere in the window)

    I could not find anyway to cast it from a QVariant in the script so I could access it properly. Also a little confused why it is casting the same object type differently.



  • Would it be possible to include the code inline here (assuming it isn't too long)?

    Thanks,
    Michael



  • main.cpp
    @
    #include <QApplication>

    #include <qdeclarative.h>
    #include <QDeclarativeView>
    #include <qdeclarativecontext.h>

    #include "object1.h"
    #include "object2.h"

    int main(int argc, char *argv[])
    {
    QApplication app(argc, argv);

    QDeclarativeView view;
    view.setResizeMode(QDeclarativeView::SizeRootObjectToView);

    qmlRegisterType<Object1>("com.test.object1", 1, 0, "Object1");
    qmlRegisterType<Object2>("com.test.object2", 1, 0, "Object2");

    Object1 *object1 = new Object1();

    view.rootContext()->setContextProperty("myObject1",object1);

    view.setSource(QUrl::fromLocalFile("main.qml"));
    view.show();

    return app.exec();
    }
    @

    main.js
    @
    function doConnect()
    {
    myObject1.mySignalSpecific.connect(displayObject)
    myObject1.mySignalQObject.connect(displayObject)
    }

    function doSomething()
    {
    var failedObject = myObject1.getObject2();
    print(failedObject);
    }

    function displayObject(obj1)
    {
    print(obj1);
    print(obj1.name);
    }
    @

    main.qml
    @
    import Qt 4.7

    import "main.js" as MainJS

    Rectangle {
    id: mainWindow

    width: 640; height: 480
    color: "lightgray"

    MouseArea
    {
    id: mouseArea
    anchors.fill: parent
    onClicked:
    {
    MainJS.doSomething();
    }
    }

    Component { Item {} }

    Component.onCompleted: MainJS.doConnect();
    }
    @

    object1.h
    @
    #ifndef OBJECT1_H
    #define OBJECT1_H

    #include <QObject>

    #include "object2.h"

    class Object1 : public QObject
    {
    Q_OBJECT

    Q_PROPERTY (QString name READ getName)
    

    public:
    Object1(QObject *parent = 0);

    public slots:
    Object2 *getObject2();
    void passObject2Script();

    signals:
    void mySignalSpecific(Object1 *obj);
    void mySignalQObject(QObject *obj);

    private:
    QString m_name;

    QString getName();
    

    };

    #endif
    @

    object1.cpp
    @
    #include "object1.h"

    #include "QTimer"

    Object1::Object1(QObject *parent) : QObject(parent)
    {
    QTimer::singleShot(1000,this,SLOT(passObject2Script()));
    m_name = "object1 name property";
    }

    Object2* Object1::getObject2()
    {
    return new Object2();
    }

    void Object1::passObject2Script()
    {
    emit mySignalSpecific(this);
    emit mySignalQObject(this);
    }

    QString Object1::getName()
    {
    return m_name;
    }
    @

    object2.h
    @
    #ifndef OBJECT2_H
    #define OBJECT2_H

    #include <QObject>
    #include <qdeclarative.h>

    class Object2 : public QObject
    {
    Q_OBJECT

    Q_PROPERTY (QString name READ getName)
    

    public:
    Object2(QObject *parent = 0);

    private:
    QString m_name;

    QString getName();
    

    };

    #endif
    @

    object2.cpp
    @
    #include "object2.h"

    Object2::Object2(QObject *parent) : QObject(parent)
    {
    m_name = "object2 name property";
    }

    QString Object2::getName()
    {
    return m_name;
    }
    @

    Console will show the output, click anywhere on the screen for the object passed directly to the view.



  • What version of Qt are you using? This sounds very similar to "QTBUG-13047":http://bugreports.qt.nokia.com/browse/QTBUG-13047, which should be fixed in 4.7.1.

    Regards,
    Michael



  • Same result on 4.7.0 and 4.7.1. From the looks of that bug report it is a different problem What I am seeing is a different cast result depending on how the signal passes the same object.



  • Okay, I'd suggest adding a new bug report then -- mySignalSpecific and mySignalQObject should be giving the same results.

    Regards,
    Michael



  • Some days ago, I tried to write some codes like you. It does not work very well. I find that it's wrong in this way.
    if you call :
    qmlRegisterType<Object1>("com.test.object1", 1, 0, "Object1");
    then you can use Object1 in qml file as Rectangle , Image, Text and so on, Object1 is only a type before you use it in qml. such as Object1{id:object_1}
    The following code, you write:
    Object1 *object1 = new Object1();
    view.rootContext()->setContextProperty("myObject1",object1);
    works good, but if you call the method of object1, the method must be Q_INVOKABLE


Log in to reply
 

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