I have 2 classes for datahandling (CGameList and CGame).
I define one GameList (_gamelist) object in qml to work with it.
I have a Listviews with show the the games from this GameList (editGames_open()).
If I click on one entry of this list, it open a new list with a detailed view of this game (editGame_open(index)).
This work works like expected.
Now my problem:
If I go back to the list and try open it again, my program crash (not every time, sometimes its work 20x times).
The crash appear after the call of getGame.
If I use the debugger I can see my CGameList-object looks fine(data a correct + item in my QList are correct), but after this the program crash with a Segmentation Fault.
The callstack show only QQMlData::wasDeleted as last entry.
I think the problem is, that my object is delete, but I cant find this.
I had try to change my QList from QList _games to QList* _games but without success.
One other thing(I think its the same problem): Sometimes getGame give back a NULL-pointer(although the game is in the list, but the data are wrong).
cgamelist.h
#ifndef CGAMELIST_H
#define CGAMELIST_H
#include <QObject>
#include <QList>
#include <qfile.h>
#include <QTextStream>
#include <QDir>
#include <QStandardPaths>
#include <QDateTime>
#include <cgame.h>
class CGameList : public QObject
{
Q_OBJECT
Q_PROPERTY(int itemCount READ getItemCount)
public:
CGameList(QObject *parent = 0);
Q_INVOKABLE bool addGame(QString name,int layout);
Q_INVOKABLE int getItemCount() const;
Q_INVOKABLE void saveGame(int index);
Q_INVOKABLE void loadGames(bool force=true);
Q_INVOKABLE CGame* getGame(int i) const;
Q_INVOKABLE QString getGamename(int i) const;
Q_INVOKABLE QString getGamedate(int i) const;
Q_INVOKABLE void delGame(int i);
private:
QList<CGame*>* _games;
};
#endif // CGAMELIST_H
cgamelist.cpp
CGameList::CGameList(QObject *parent) : QObject(parent)
{
_games=new QList<CGame*>();
_games->clear();
}
...
CGame* CGameList::getGame(int i) const
{
/* CGame*g=new CGame();
g->setGamename("test");
return g;*/
try
{
return _games->at(i);
}
catch(...)
{
return NULL;
}
}
...
cgame.h*
#ifndef CGAME_H
#define CGAME_H
#include <QObject>
#include <QString>
#include <QDateTime>
class CGame : public QObject
{
Q_OBJECT
Q_PROPERTY(QString gamename READ getGamename WRITE setGamename)
Q_PROPERTY(int itemCount READ getItemCount)
Q_PROPERTY(int layout READ getLayout WRITE setLayout)
Q_PROPERTY(int duration READ getDuration WRITE setDuration)
Q_PROPERTY(QDateTime date READ getDate WRITE setDate)
public:
CGame(QObject *parent = 0);
Q_INVOKABLE QString getGamename() const;
Q_INVOKABLE void setGamename(QString name);
Q_INVOKABLE int getItemCount() const;
Q_INVOKABLE int getLayout() const;
Q_INVOKABLE void setLayout(int layout);
Q_INVOKABLE int getDuration() const;
Q_INVOKABLE void setDuration(int duration);
Q_INVOKABLE QDateTime getDate() const;
Q_INVOKABLE void setDate(QDateTime date);
Q_INVOKABLE QString getEvent(int i) const;
Q_INVOKABLE void addEvent(QString ename,int time,int sec,int duration);
private:
QString _name;
int _layout;
int _duration;
QList<QString>* _events;
QDateTime _date;
};
#endif // CGAME_H
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QtQml>
#include "clayoutlist.h"
#include "clayout.h"
#include "clayoutitem.h"
#include "cgame.h"
#include "cgamelist.h"
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
//QApplication app(argc, argv);
QQmlApplicationEngine engine;
qmlRegisterType<CLayoutList>("STSP.Tag",1,0,"TagLayoutList");
qmlRegisterType<CLayout>("STSP.Tag",1,0,"TagLayout");
qmlRegisterType<CLayoutItem>("STSP.Tag",1,0,"TagLayoutItem");
qmlRegisterType<CGame>("STSP.Tag",1,0,"Game");
qmlRegisterType<CGameList>("STSP.Tag",1,0,"GameList");
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
return app.exec();
}
main.qml
import QtQuick 2.5
import QtQuick.Controls 1.4
import QtQuick.Dialogs 1.2
import QtQuick.Window 2.2
import STSP.Tag 1.0
ApplicationWindow {
TagLayoutList {
id: _layoutlist
}
GameList
{
id:_gamelist
}
visible: true
MainForm {
id: mainform
anchors.fill: parent
}
MessageDialog{
id:info
}
...
function editGames_open()
{
_gamelist.loadGames()
mainform.p_gameslistmodel.clear()
var i
for (i = 0; i < _gamelist.getItemCount(); i++) {
mainform.p_gameslistmodel.append({
name: _gamelist.getGamename(i),
date: _gamelist.getGamedate(i),
gameindex: i
})
}
mainform.p_editgames.delmode=false
mainform.p_editgames.visible = true
mainform.p_startmenu.visible=false
}
function editGame_open(index)
{
mainform.p_eventlistmodel.clear()
var game={}
try
{
game=_gamelist.getGame(index)
}
catch(exc)
{
console.log("Serious Error 2 "+exc)
return
}
if(game==null)
{
console.log("Reload Games")
_gamelist.loadGames()
game=_gamelist.getGame(index)
}
if(game==null)
{
console.log("Error Game not found")
return
}
var i
var event
var events
var t,s,m,h
for(i=0;i<game.getItemCount();i++)
{
event=game.getEvent(i).split('#')[1]
//console.log(event)
events=event.split(',')
t=events[1]
s=t%60
t=(t-s)/60
m=t%60
h=(t-m)/60
mainform.p_eventlistmodel.append({
name: events[0],
time: h+":"+(m<10?"0":"")+m+":"+(s<10?"0":"")+s,
eventindex: i
})
}
mainform.p_editgame.gname=game.getGamename()
t=game.getDuration()
s=t%60
t=(t-s)/60
m=t%60
h=(t-m)/60
mainform.p_editgame.gtime=h+":"+(m<10?"0":"")+m+":"+(s<10?"0":"")+s
mainform.p_editgames.delmode=false
mainform.p_editgames.visible=false
mainform.p_editgame.visible=true
}
function editGame_back()
{
mainform.p_editgame.visible=false
mainform.p_editgames.visible=true
}