Qt Forum

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

    The Famous 'QMetaProperty::read: Unable to handle unregistered datatype' error

    QML and Qt Quick
    3
    9
    11762
    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.
    • L
      LonniB last edited by

      Hello everyone,

      For starters, I'm fairly new to Qt and QML and still just an intern in my firm, so please accept my apologies if I am asking dumb questions.

      Ok so here I go with my problem. I'm having the QMetaProperty::read: Unable to handle unregistered datatype error with my example. I am basically just re-coding myself the mine hunt program example. And here's the thing, whether I launch my own code or the one provided online for that I get @QMetaProperty::read: Unable to handle unregistered datatype 'QDeclarativeListProperty<Tile>' for property 'MineSweeperGame::tiles'@

      Here's my code:

      main.cpp :
      @#include <QtGui/QGuiApplication>
      #include <QApplication>
      #include <QtDeclarative/QDeclarativeView>
      #include <QtDeclarative/QDeclarativeContext>
      #include <QtDeclarative/QDeclarativeEngine>
      #include <QtQuick/QQuickPaintedItem>

      #include "qtquick2applicationviewer.h"
      #include "minesweepergame.h"

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

      QApplication app(argc, argv);
      QDeclarativeView canvas;
      
      qRegisterMetaType<Tile>("Tile");
      
      MineSweeperGame* g = new MineSweeperGame();
      

      #ifdef Q_OS_SYMBIAN
      canvas.setResizeMode(QDeclarativeView::SizeRootObjectToView);
      #endif
      canvas.engine()->rootContext()->setContextObject(g);
      canvas.setSource(QString("../Resources/qml/MyMineSweeper/main.qml"));
      QObject::connect(canvas.engine(), SIGNAL(quit()), &app, SLOT(quit()));

      #ifdef Q_OS_SYMBIAN
      canvas.showFullScreen();
      #else
      canvas.setGeometry(QRect(100, 100, 450, 450));
      canvas.show();
      #endif

      return app.exec();
      

      }
      @

      tile.h :
      @#ifndef TILE_H
      #define TILE_H
      #include <QObject>
      #include <QMetaType>

      class Tile : public QObject
      {
      Q_OBJECT
      private:

      bool _flipped ;
      bool _hasMine ;
      bool _hasFlag ;
      int _nbMines ;
      

      public:
      Tile():_flipped(false), _hasMine(false), _hasFlag(false), _nbMines(-1) {}

      Tile(const Tile &other):_flipped(other._flipped), _hasMine(other._hasMine), _hasFlag(other._hasFlag), _nbMines(other._nbMines){}
      
      ~Tile(){}
      
      Q_PROPERTY(bool flipped READ flipped WRITE setFlipped NOTIFY flippedChanged)
      bool flipped();
      void setFlipped(bool b);
      
      Q_PROPERTY(bool hasMine READ hasMine WRITE setHasMine NOTIFY hasMineChanged)
      bool hasMine();
      void setHasMine(bool b);
      
      Q_PROPERTY(bool hasFlag READ hasFlag WRITE setHasFlag NOTIFY hasFlagChanged)
      bool hasFlag();
      void setHasFlag(bool b);
      
      Q_PROPERTY(int nbMines READ nbMines WRITE setNbMines NOTIFY nbMinesChanged)
      int nbMines();
      void setNbMines(int nb);
      

      signals:
      void flippedChanged();
      void hasMineChanged();
      void hasFlagChanged();
      void nbMinesChanged();

      };
      Q_DECLARE_METATYPE(Tile)
      #endif // TILE_H
      @

      MineSweeper.h :
      @#ifndef MINESWEEPERGAME_H
      #define MINESWEEPERGAME_H

      #include <tile.h>

      #include <QObject>
      #include <QList>
      #include <QDeclarativeListProperty>

      class MineSweeperGame : public QObject{

      Q_OBJECT
      

      private:
      bool onBoard(int row, int col) const;

      Tile* tile(int row, int col);
      
      int getHint(int row, int col);
      
      void setPlaying(bool b);
      
      QList<Tile *> _tiles ;
      int numCols ;
      int numRows ;
      bool playing ;
      bool won ;
      int remaining ;
      int nMines ;
      int nFlags ;
      

      public:
      MineSweeperGame();

      Q_PROPERTY(QDeclarativeListProperty<Tile> tiles READ tiles CONSTANT)
      QDeclarativeListProperty<Tile> tiles();
      
      Q_PROPERTY(bool isPlaying READ isPlaying NOTIFY hasPlayingChanged)
      bool isPlaying()  {return playing;}
      
      Q_PROPERTY(bool hasWon READ hasWon NOTIFY hasWonChanged)
      bool hasWon()  {return won;}
      
      Q_PROPERTY(int numMines READ numMines NOTIFY numMinesChanged)
      int numMines() const {return nMines;}
      
      Q_PROPERTY(int numFlags READ numFlags NOTIFY numFlagsChanged)
      int numFlags() const {return nFlags;}
      

      public slots:
      Q_INVOKABLE bool flip(int row, int col);
      Q_INVOKABLE bool flag(int row, int col);
      void setBoard();
      void reset();

      signals:
      void hasPlayingChanged();
      void hasWonChanged();
      void numMinesChanged();
      void numFlagsChanged();
      };

      #endif // MINESWEEPERGAME_H
      @

      tile.cpp :
      @#include "tile.h"

      bool Tile::flipped(){
      return _flipped ;
      }

      void Tile::setFlipped(bool b){
      if (_flipped == b){
      return ;
      }
      _flipped = b ;
      emit flippedChanged();
      }

      bool Tile::hasMine(){
      return _hasMine ;
      }

      void Tile::setHasMine(bool b){
      if(_hasMine==b){
      return ;
      }
      _hasMine = b ;
      emit hasMineChanged();
      }

      bool Tile::hasFlag(){
      return _hasFlag ;
      }

      void Tile::setHasFlag(bool b){
      if(_hasFlag==b){
      return ;
      }
      _hasFlag = b ;
      emit hasFlagChanged();
      }

      int Tile::nbMines(){
      return _nbMines ;
      }

      void Tile::setNbMines(int nb){
      if(_nbMines == nb){
      return ;
      }
      _nbMines = nb ;
      emit nbMinesChanged();
      }

      @

      Since the QML code is not complete there is no point in giving them to ya now.
      Thanks in advance.

      Cheers,

      LB

      1 Reply Last reply Reply Quote 0
      • S
        stevenceuppens last edited by

        Hi,

        Do you register "Tile" with the QML type system via qmlRegisterType()?

        Steven CEUPPENS
        Developer &#x2F; Architect
        Mobile: +32 479 65 93 10

        1 Reply Last reply Reply Quote 0
        • L
          LonniB last edited by

          Yes I did. I tried with qRegisterType<Tile>() and qRegisterType<Tile>("Tile") in my main.cpp. Does not work :(

          1 Reply Last reply Reply Quote 0
          • S
            stevenceuppens last edited by

            And also with:

            qmlRegisterType<Tile>("Tile");

            instead of

            qRegisterMetaType<Tile>("Tile");

            :)

            Steven CEUPPENS
            Developer &#x2F; Architect
            Mobile: +32 479 65 93 10

            1 Reply Last reply Reply Quote 0
            • L
              LonniB last edited by

              Well it seems that qmlRegisterType<Tile>("Tile") is not a valid function call.
              However I tried qmlRegisterType<Tile>() and I do get the exact same error ><

              1 Reply Last reply Reply Quote 0
              • L
                LonniB last edited by

                In case you find it easier to have my whole code here it goes : "https://dl.dropboxusercontent.com/u/30965278/MyMineSweeper.zip":https://dl.dropboxusercontent.com/u/30965278/MyMineSweeper.zip

                1 Reply Last reply Reply Quote 0
                • L
                  LonniB last edited by

                  Up :)

                  1 Reply Last reply Reply Quote 0
                  • C
                    chrisadams last edited by

                    Please see the documentation for the qmlRegisterType function at http://qt-project.org/doc/qt-5/qqmlengine.html#qmlRegisterType

                    You need to call it like:

                    @
                    qmlRegisterType<Tile>("com.your.namespace", 1, 0, "Tile");
                    @

                    Then, the code which uses that Tile type within QML needs to ensure that it does

                    @
                    import com.your.namespace 1.0
                    @

                    in order to have access to that type information.

                    Cheers,
                    Chris.

                    1 Reply Last reply Reply Quote 0
                    • L
                      LonniB last edited by

                      Alright i will try to do that !
                      However, I am not using a namespace therefore I don't know if that is really relevent is it?

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