Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Casting signaled QObjects from C++ code
Forum Updated to NodeBB v4.3 + New Features

Casting signaled QObjects from C++ code

Scheduled Pinned Locked Moved QML and Qt Quick
7 Posts 3 Posters 5.1k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • C Offline
    C Offline
    coderbob
    wrote on last edited by
    #1

    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.

    1 Reply Last reply
    0
    • M Offline
      M Offline
      mbrasser
      wrote on last edited by
      #2

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

      Thanks,
      Michael

      1 Reply Last reply
      0
      • C Offline
        C Offline
        coderbob
        wrote on last edited by
        #3

        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.

        1 Reply Last reply
        0
        • M Offline
          M Offline
          mbrasser
          wrote on last edited by
          #4

          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

          1 Reply Last reply
          0
          • C Offline
            C Offline
            coderbob
            wrote on last edited by
            #5

            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.

            1 Reply Last reply
            0
            • M Offline
              M Offline
              mbrasser
              wrote on last edited by
              #6

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

              Regards,
              Michael

              1 Reply Last reply
              0
              • I Offline
                I Offline
                imxiangpeng
                wrote on last edited by
                #7

                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

                1 Reply Last reply
                0

                • Login

                • Login or register to search.
                • First post
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • Users
                • Groups
                • Search
                • Get Qt Extensions
                • Unsolved