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();
#endifreturn 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()?
-
And also with:
qmlRegisterType<Tile>("Tile");
instead of
qRegisterMetaType<Tile>("Tile");
:)
-
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
-
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.