Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

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



  • 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



  • Hi,

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



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



  • And also with:

    qmlRegisterType<Tile>("Tile");

    instead of

    qRegisterMetaType<Tile>("Tile");

    :)



  • 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 ><





  • Up :)



  • 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.



  • 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?


Log in to reply