SetData or reading from new row crashes
-
Silly question: did you initialise modelBox ?
-
@SGaist
Yes my modelBox is initialized in my headerpublic: QStandardItemModel *modelBox;
And I have a function which loads my sqlite data in.
I do know what the problem is now, but not how to solve it.
I am using the dataChanged signal to run my code when a table row is changed. egQObject::connect(modelBox,&QAbstractItemModel::dataChanged,this,&DbManager::updateBoxList);
The signal works fine and calls my code when I edit a row and hit enter.
The problem is this which I have just discovered. The dataChanged signal is firing when I do this
void DbManager::addRowBox(){ qDebug() << "Add"; modelBox->insertRow(0); }
So what is happening my code is being called before I have edited the line which is causing the crash.
First of all I don't know why the signal is firing when I add a row, and I am not sure what to do instead.
-
No it's not.
modelBox
is just declared in your header, which means that you are trying to use an invalid pointer hence your crash. -
I said my model is setup in a function. I declare it in the header so I can use it in all functions in my class. The problem is that the dataChanged signal is firing when I insert a row. It should only fire when data is changed, and not when I add a row. My actual code for setting up the model is here.
void DbManager::boxList(){ QSqlQuery query; query.prepare("select `boxID`,`boxName`,`boxLocation` from `boxes`"); query.exec(); modelBox= new QStandardItemModel(sqlSize(query), 3); int i=0; while (query.next()) { modelBox->setData(modelBox->index(i, 0), query.value("boxID")); modelBox->setData(modelBox->index(i, 1), query.value("boxName")); modelBox->setData(modelBox->index(i, 2), query.value("boxLocation")); i++; } modelBox->setHeaderData(1, Qt::Horizontal, QObject::tr("Box ID / Name")); modelBox->setHeaderData(2, Qt::Horizontal, QObject::tr("Box Location")); QObject::connect(modelBox,&QAbstractItemModel::dataChanged,this,&DbManager::updateBoxList); }
The model is working fine. If I click on a table row I can edit it no problem. It is only when I insert a new row it is not working, and that is because dataChanged is firing when I insert the row, instead of firing when I click enter after changing the row. If I edit an existing row dataChange fires when it should.
-
I have a solution, but I don't know if it is the best solution as of yet.
Because the crash was being caused by the signal being fired when I added a new row, my solution was to disconnect the signal when I add a new row., and re-connect the signal afterwards egvoid DbManager::addRowBox(){ qDebug() << "Add"; disconnect(modelBox,&QAbstractItemModel::dataChanged,this,&DbManager::updateBoxList); modelBox->insertRow(0); QObject::connect(modelBox,&QAbstractItemModel::dataChanged,this,&DbManager::updateBoxList); }
That let me edit the row, which was great, but it was still crashing when I hit the enter key. You see when you run the following lines and any of the columns are null data it will crash.
QString boxID = modelBox->item(topLeft.row(),0)->text(); QString boxName = modelBox->item(topLeft.row(),1)->text(); QString boxLocation = modelBox->item(topLeft.row(),2)->text();
So the answer was this. I add dummy data. For the id column I will add the text "Add". It doesn't matter what I put in this column because on an insert an id is not needed. I will just use this to check if the data needs to be inserted or updated.
So here is the solution
void DbManager::addRowBox(){ qDebug() << "Add"; disconnect(modelBox,&QAbstractItemModel::dataChanged,this,&DbManager::updateBoxList); modelBox->insertRow(0); modelBox->setData(modelBox->index(0, 0),"add"); modelBox->setData(modelBox->index(0, 1),""); modelBox->setData(modelBox->index(0, 2),""); QObject::connect(modelBox,&QAbstractItemModel::dataChanged,this,&DbManager::updateBoxList); }
So the solution is in two parts. The first part is to disconnect the dataChanged signal. Then add the row, and then add dummy data. Then the dummy data will stop it crashing when you hit enter and haven't filled in all the columns. Adding a "" to the cell will stop it being a null cell, and will stop it crashing.
In a few days if nobody has given me a better solution I will mark this as solved, but I will leave it open for a while in case somebody has a better way of doing this. I had to come up with a solution myself because nobody else came up with one. I do believe there may be a better way of doing this though.
-
Can you show the stack trace of your crash ?
There's something fishy.
Otherwise, you can use blockSignals.
-
@SGaist
Now I am disconnecting and adding the row it isn't crashing anymore.I would really love to give you a stack trace, but I don't know how.
I spent 2 days googling how to do a stack trace in QT and couldn't find any help at all.When I find a tutorial or some help on how to do a stack trace, I will certainly give you one.
-
Build your application in debug mode, start a debugging session, make it crash and you'll have the stack trace.
-
@SGaist
I quoted out the disconnect to purposely cause the crash again. Then run in debug mode, which is actually what I always run it in.Went to menu Debug, and clicked on start debuggin (F5) and I get a message window pop up "Unknown debugger type
no engine
. Unable to create a debugger typeno engine
".So the debugger does not seem to work.
-
Did you install one ? Which OS are you running with which compiler?