I am having some sort of problem with Q_PROPERTY
-
Please forgive me I have made a class when at this point I don't need one.
Anyway I get these errors:moc_tiledata.obj:-1: error: LNK2005: "public: void __cdecl TileData::tilesChanged(void)" (?tilesChanged@TileData@@QEAAXXZ) already defined in tiledata.obj moc_tiledata.obj:-1: error: LNK2005: "public: void __cdecl TileData::locxChanged(void)" (?locxChanged@TileData@@QEAAXXZ) already defined in tiledata.obj moc_tiledata.obj:-1: error: LNK2005: "public: void __cdecl TileData::locyChanged(void)" (?locyChanged@TileData@@QEAAXXZ) already defined in tiledata.obj moc_tiledata.obj:-1: error: LNK2005: "public: void __cdecl TileData::locmChanged(void)" (?locmChanged@TileData@@QEAAXXZ) already defined in tiledata.obj C:\Users\damon\Documents\QT\build-skydevils-Desktop_Qt_5_15_2_MSVC2015_64bit-Debug\debug\skydevils.exe:-1: error: LNK1169: one or more multiply defined symbols found
main.cpp:
#include <QGuiApplication> #include <QQmlApplicationEngine> #include "tiledata.h" #include <QQmlContext> int main(int argc, char *argv[]) { #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); #endif QGuiApplication app(argc, argv); qmlRegisterType<TileData>("com.andyindustries.tiledata",1,0,"TileData"); QQmlApplicationEngine engine; const QUrl url(QStringLiteral("qrc:/main.qml")); QObject::connect(&engine, &QQmlApplicationEngine::objectCreated, &app, [url](QObject *obj, const QUrl &objUrl) { if (!obj && url == objUrl) QCoreApplication::exit(-1); }, Qt::QueuedConnection); engine.load(url); return app.exec(); }
mymap.h:
#ifndef MYMAP_H #define MYMAP_H #include <QtCore> class MyMap { public: ~MyMap(); void setMap(QString ins); int maxx; int maxy; int **tiles; }; #endif // MYMAP_H
mymap.cpp:
#include "mymap.h" MyMap::~MyMap() { } void MyMap::setMap(QString ins) { bool readx = true; int numx = 1; int numy = 1; for(int i=0;i<ins.length();i++){ if(ins.mid(i,1) == "\n"){ readx = false; numy++; } if (readx && ins.mid(i,1) == ",") numx++; } maxx = numx; maxy = numy; tiles = new int *[numx]; for (int i=0;i<numx;i++) tiles[i] = new int[numy]; int curnum = 0; int placx = 0; int placy = 0; for(int i=0;i<ins.length();i++){ if (ins.at(i).toLatin1() > 47 && ins.at(i).toLatin1() < 59){ curnum *= 10; curnum += ins.at(i).toLatin1() - 48; if (i == ins.length() - 1) tiles[placx][placy] = curnum; } if (ins.mid(i,1) == "," || ins.mid(i,1) == "\n"){ tiles[placx][placy] = curnum; curnum = 0; placx++; if (placx == numx){ placx = 0; placy++; } } } }
tiledata.h:
#ifndef TILEDATA_H #define TILEDATA_H #include <QObject> #include <QFile> #include <QTextStream> #include <QDebug> #include "mymap.h" class TileData : public QObject { Q_OBJECT Q_PROPERTY(int tiles READ tiles WRITE settiles NOTIFY tilesChanged) Q_PROPERTY(int plocx READ plocx WRITE setplocx NOTIFY locxChanged) Q_PROPERTY(int plocy READ plocy WRITE setplocy NOTIFY locyChanged) Q_PROPERTY(int plocm READ plocm WRITE setplocm NOTIFY locmChanged) public: explicit TileData(QObject *parent = nullptr); int tiles(); int plocx(); int plocy(); int plocm(); void settiles(int inv); void setplocx(int inv); void setplocy(int inv); void setplocm(int inv); signals: void tilesChanged(); void locxChanged(); void locyChanged(); void locmChanged(); private: int locx; int locy; int locm; QVector<MyMap> myMaps; }; #endif // TILEDATA_H
tiledata.cpp
#include "tiledata.h" TileData::TileData(QObject *parent) : QObject(parent) { QString inDat; QFile fil("/tileref/tiledata.csv"); if(!fil.open(QFile::ReadOnly | QFile::Text)){ } QTextStream in(&fil); inDat = in.readAll(); fil.close(); MyMap tempM; tempM.setMap(inDat); myMaps.push_back(tempM); } int TileData::tiles() { if (locx > -1 && locx < myMaps.at(locm).maxx && locy > -1 && locy < myMaps.at(locm).maxy && locm < myMaps.size()){ return myMaps.at(locm).tiles[locx][locy]; }else{ return -1; } emit tilesChanged(); } int TileData::plocx() { return locx; } int TileData::plocy() { return locy; } int TileData::plocm() { return locm; } void TileData::settiles(int inv) { } void TileData::setplocx(int inv) { locx = inv; emit locxChanged(); } void TileData::setplocy(int inv) { locy = inv; emit locyChanged(); } void TileData::setplocm(int inv) { locm = inv; emit locmChanged(); } void TileData::tilesChanged(){ } void TileData::locxChanged(){ } void TileData::locyChanged(){ } void TileData::locmChanged(){ }
and now my Qml which is main.qml:
import QtQuick 2.12 import QtQuick.Window 2.12 import QtQuick.Dialogs 1.2 import QtQuick.Controls 2.5 import com.andyindustries.tiledata 1.0 ApplicationWindow { width: 640 height: 600 visible: true title: qsTr("******") // censord property bool needLoad: true property int curframe: 0 property var frameVals: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] TileData{ id:td } Timer{ interval: 50; running: true; repeat: true onTriggered:{ if (needLoad){ td.locm = 0; for (var y=0;y<5;y++){ td.plocy = y; for (var x=0;x<5;x++){ td.plocx = x; frameVals[x + y * 5] = td.tiles; } } needLoad = false; } curframe = (curframe + 1) % 4 mycanvas.requestPaint() } } function getName(inv){ var retv = "/images/bloc"; var part = 0; for (var i=0;i<4;i++){ part = Math.floor(inv / Math.pow(16, (3 - i))) % 16 if (part > 9){ retv += String.fromCharCode(55 + part) }else{ retv += String.fromCharCode(48 + part) } } retv += ".png" return retv } function fldName(inv){ var retv = "/images/field"; retv += String.fromCharCode(48 + inv) retv += ".png" return retv } Canvas{ id: mycanvas anchors.centerIn: parent width: 512 height: 512 property string oneEl: "" Component.onCompleted: { for (var i=0;i<10;i++){ oneEl = getName(i) loadImage(mycanvas.oneEl); } oneEl = getName(65535); loadImage(oneEl) for (var j=0;j<8;j++){ oneEl = fldName(j) loadImage(mycanvas.oneEl); } } onPaint: { var ctx = getContext("2d"); for (var y=0;y<5;y++){ for (var x=0;x<5;x++){ if (frameVals[x + y * 5] < 10000 || frameVals[x + y * 5] == 65535){ oneEl = getName(frameVals[x + y * 5]); }else{ switch (frameVals[x + y * 5]){ case 65531: oneEl = fldName(curframe) break; case 65532: oneEl = fldName(curframe + 4); break; case 65533: oneEl = fldName(3 - curframe) break; case 65534: oneEl = fldName(3 - curframe + 4) break; } } ctx.drawImage(mycanvas.oneEl,x * 96,y * 96) } } } } }
-
@AI_Messiah said in I am having some sort of problem with Q_PROPERTY:
In tiledata.cpp:void TileData::tilesChanged()
One doesn't implement signals, the moc does that for you. Remove these. Btw the linker is more than descriptive here (emphasis mine):
moc_tiledata.obj:-1: error: LNK2005: "public: void __cdecl TileData::tilesChanged(void)" (?tilesChanged@TileData@@QEAAXXZ) already defined in tiledata.objAlso seems appropriate you also read this:
https://en.wikipedia.org/wiki/One_Definition_Rule -
I did what you said, there was one thing that I had to change that you would have overlooked, but this loads the tile = 0 for all tiles.