Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Call for Presentations - Qt World Summit

    QML and C++ Integration [solved]

    QML and Qt Quick
    3
    6
    2136
    Loading More Posts
    • 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.
    • R
      runslow last edited by

      Hello,

      I have gotten communication from c++ and QML using the Q_PROPERTY macro with basic types such as QString and int, but I cannot get it to work with my own custom class that extends QObject. Here is my Code:

      //simple.h
      @#include <QObject>
      #include <QMetaType>

      class Simple : public QObject
      {
      Q_Object
      Q_PROPERTY(int hour READ getHour WRITE setHour NOTIFY hourChanged)

      public:
      explicit Simple(QObject *parent = 0);
      int getHour();
      void setHour(int hour);

      signals:
      void hourChanged(int);

      private:
      int _hour;
      };

      Q_DECLARE_METATYPE(Simple*)
      @

      //simple.cpp
      @#include "simple.h"

      Simple::Simple(QObject *parent)
      : QObject(parent)
      {
      _hour = 129;
      }

      int Simple::getHour() {
      return _hour;
      }

      void Simple::setHour(int hour) {
      _hour = hour;
      emit hourChanged(_hour);
      }
      @

      //step.h
      @#include <QObject>
      #include <QMetaType>
      #include "simple.h"

      class Step : public QObject
      {
      Q_OBJECT
      Q_PROPERTY(Simple* sim READ getSim)

      public:
      explicit Step(QObject parent = 0);
      Simple
      getSim();

      private:
      Simple* _sim;
      };
      @

      //step.cpp
      @#include "step.h"

      Step::Step(QObject parent)
      : QObject(parent)
      {
      qRegisterMetaType<Simple
      >("Simple");
      _sim = new Simple();
      }

      Simple* Step::getSim() {
      return _sim;
      }
      @

      //main.cpp
      @#include <QtGui/QGuiApplication>
      #include "qtquick2applicationviewer.h"
      #include <QQmlContext>
      #include "step.h"

      int main(int argc, char *argv[])
      {
      QGuiApplication app(argc, argv);
      QtQuick2ApplicationViewer viewer;

       Step step;
       viewer.rootContext()->setContextProperty("step", &step);
      
       viewer.setMainQmlFile&#40;QStringLiteral("qml/Cineflux_001/main.qml"&#41;&#41;;
       viewer.showExpanded(&#41;;
       return app.exec(&#41;;
      

      }
      @

      //main.qml
      @import QtQuick 2.0

      Rectangle {
      width: 200; height: 200;

       Component.onCompleted: {
            console.log(step.sim&#41;; //prints QVariant(Simple*&#41;
            console.log(step.sim.hour) //prints undefined
       }
      

      }
      @

      I do not understand why step.min prints the object, but when I try and access the hour property it gives me undefined. Is this because the c++ object is a pointer? I am not sure. I have fiddled with this a lot and I either get META compile errors or undefined. Please help me.

      Thank you

      1 Reply Last reply Reply Quote 0
      • F
        favoritas37 last edited by

        Hello. First of all, at the class declaration of Simple, i suppose you mean that the base object is QObject not Simple, right?

        So for your problem. With the following changes it worked for me, though i dont know if there is a better/cleaner way:

        In Simple.h remove the
        @
        Q_DECLARE_METATYPE(Simple*)
        @

        In main.cpp add:
        @
        qmlRegisterType<Simple>("CustomObjects", 1, 0, "Simple");
        @

        In main.qml add:
        @
        import CustomObjects 1.0
        @

        Now try and see what happends :P

        PS: a final info. The following Q_DECLARE_METATYPE(Simple*) doen't work for you because you are registering just a pointer, not the class it self. So for it to work you should use it as follows:
        @
        Q_DECLARE_METATYPE(Simple)
        @

        But in that case you need to create copy constructor, overload the operator= and implement a destructor. I have tried it and it didn't work at the first round, may be you will be more lucky. Oh and if you try it, don't forget to add somewhere the line:
        @
        qRegisterMetaType<Simple>("Simple");
        @

        Regards!

        1 Reply Last reply Reply Quote 0
        • R
          runslow last edited by

          Yes, the class declaration was a typo ;/

          I do not want to initialize the c++ object in QML, rather I just want to access it. So the qmlRegisterType will not work.

          I tried overloading the =operator, without any luck. According to this it is not possible:

          http://qt-project.org/doc/qt-4.8/object.html#qt-objects-identity-vs-value

          I get a couple compile time errors notably:
          error: 'QObject::QObject(const QObject&)' is private
          synthesized method 'Simple::Simple(const Simple&)' first required here

          Any other thoughts?

          Thank you for your help.

          1 Reply Last reply Reply Quote 0
          • T
            tzander last edited by

            The qmlRegisterType is not needed in your limited case; its useful to have it when you use the Q_ENUMS macro, though.

            1 Reply Last reply Reply Quote 0
            • T
              tzander last edited by

              Maybe you can try changing
              Q_PROPERTY(Simple* sim READ getSim)
              to
              Q_PROPERTY(QObject* sim READ getSim)

              you should be able to leave the rest as is.

              1 Reply Last reply Reply Quote 0
              • R
                runslow last edited by

                Thank you very much Thomas. That sure did the trick. You rock!

                1 Reply Last reply Reply Quote 0
                • First post
                  Last post