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. How to send Qt signals with non basic types to a QML script
Forum Updated to NodeBB v4.3 + New Features

How to send Qt signals with non basic types to a QML script

Scheduled Pinned Locked Moved QML and Qt Quick
4 Posts 4 Posters 2.5k 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.
  • T Offline
    T Offline
    Tom C
    wrote on last edited by
    #1

    Hello !!

    I have two classes, Map and Position, both are derivate from QObject.
    I have a QML script which display a Position object.

    I'm trying to send a signal (from a Map object) holding a Position object to update my QML srcipt. But i got the following message when the signal occurs:

    bq. QMetaProperty::read: Unable to handle unregistered datatype 'Position' for property 'QDeclarativeBoundSignalParameters::newPosition'

    bq. app.qml:10: TypeError: Result of expression 'newPosition' [undefined] is not an object.

    Here my code:

    @
    #ifndef POSITION_H
    #define POSITION_H

    #include <QObject>

    class Position : public QObject
    {
    Q_OBJECT
    Q_PROPERTY(double latitude READ latitude WRITE setLatitude)
    Q_PROPERTY(double longitude READ longitude WRITE setLongitude)

    public:
    Position(double latitude = 0, double longitude = 0,QObject *parent = 0);
    Position(const Position & other);
    Position & operator =( const Position & other);
    bool operator !=(const Position &);

    double latitude();
    void setLatitude(double);
    
    double longitude();
    void setLongitude(double);
    

    private:
    double m_lat;
    double m_lon;
    };

    #endif // POSITION_H
    @

    @
    #ifndef MAP_H
    #define MAP_H

    #include <QObject>

    #include "position.h"

    class Map : public QObject
    {
    Q_OBJECT

    Q_PROPERTY(Position center READ center WRITE setCenter NOTIFY centerChanged)
    

    public:
    explicit Map(QObject *parent = 0) :
    QObject(parent)
    {}

    Position center() const{
        return m_center;
    }
    void setCenter(const Position & other){
        if( m_center != other ){
            m_center = other;
            emit centerChanged(m_center);
        }
    }
    

    signals:
    void centerChanged(Position newPosition);

    private:
    Position m_center;
    };

    #endif // MAP_H
    @

    @
    import QtQuick 1.0
    import Localisation 1.0

    Item {
    width: 300; height: 200

    Connections{
        target: myMap
        onCenterChanged: {
            //perform action with newPosition, e.g :
            text.text = newPosition.latitude + ", " + newPosition.longitude
        }
    }
    
    Text{
        id: text
        anchors.centerIn: parent
        text: "Wait an update"
    }
    

    }
    @

    @
    #include <QApplication>
    #include <QtDeclarative>
    #include <QDeclarativeView>

    #include "map.h"
    #include "position.h"

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

    qmlRegisterType<Position>("Localisation",1,0,"Position");
    
    Map myMap;
    QDeclarativeView view;
    view.rootContext()->setContextProperty("myMap",&myMap);
    view.setSource(QUrl::fromLocalFile&#40;"app.qml"&#41;);
    view.show();
    
    return a.exec&#40;&#41;;
    

    }
    @

    1 Reply Last reply
    0
    • D Offline
      D Offline
      dmcr
      wrote on last edited by
      #2

      Hello,

      first of all, i would use QDeclarativeItem instead of QObject for using an object in QML.

      Then i may use the object connections, but the target had to be an QML item, which is not exactly in your code (it is more a "binding" done with setContextProperty)

      dmcr

      1 Reply Last reply
      0
      • T Offline
        T Offline
        tolszak
        wrote on last edited by
        #3

        Try with:

        @
        qmlRegisterType<Position>();
        @

        and if it doesn't work maybe additionally with:

        @
        qmlRegisterType<Map> ();
        @

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

          You know that instead of adding new clas you could use QPointF:
          @
          //.h file
          class Map : public QObject
          {
          Q_OBJECT
          Q_PROPERTY(QPointF center READ getCenter NOTIFY centerChanged)

          public:
          explicit Map(QObject *parent = 0);

          inline QPointF getCenter() const;
          void setCenter(const QPointF& aCenter);
          

          signals:
          void centerChanged();
          public slots:
          void blabla();

          private:
          QPointF m_center;
          };

          QPointF Map::getCenter() const
          {
          return m_center;
          }

          //.cpp file
          void Map::setCenter(const QPointF &aCenter)
          {
          if (aCenter == m_center)
          return;

          m_center = aCenter;
          emit centerChanged();
          

          }

          //Part of qml file
          Connections {
          target: myMap
          onCenterChanged: {
          myTxt.text = "x " + myMap.center.x + " y " + myMap.center.y
          }
          }
          @

          If you want to use longitude and latitude keywords you can do:
          @
          //.h file
          Q_PROPERTY(QVariant center READ getCenter NOTIFY centerChanged)
          //...
          QVariant getCenter() const;

          //.cpp file
          QVariant Map::getCenter() const
          {
          QMap<QString, QVariant> centerMap;
          centerMap.insert("longitude",m_center.x());
          centerMap.insert("latitude",m_center.y());

          return centerMap;
          

          }

          //.qml file
          Connections {
          target: myMap
          onCenterChanged: {
          myTxt.text = "x " + myMap.center.longitude + " y " + myMap.center.latitude
          }
          }
          @

          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