PDA

View Full Version : Deleting QSqlTableModel and QTableView



waynew
22nd December 2009, 03:03
Ok, I'm stumped.
When I call openLog from the mainwindow menu, the existing model and view are deleted and replaced by the selected new ones. Works perfectly.
But, when I call openLog from a dialog via the mainwindow menu, to create and open a new database, it crashes when it tries to delete the current model and view.



void MainWindow::openLog(QString logName) {
delete model; // existing
delete view; // existing

QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName(logName + ".log.sqlite");
db.open();
model = new QSqlTableModel();
view = new QTableView();

model->setTable("log");
//etc ...


But... this crashes unless I comment out the delete model and delete view lines.



void NewLog::createLog() {
QString log = m_ui->nlName->text();

MainWindow mw;
mw.openLog(log);
NewLog::close();
}

tangential
22nd December 2009, 05:06
This looks like a stock segfault, at first look I'd check the pointers for NULL before deletion, but that shouldn't be necessary if the c++ compiler's following specs.

First things first, can you post us a stacktrace? :)

waynew
22nd December 2009, 23:33
I'm pretty much a newbie at C++ and Qt, but here is what I got from the debug process:

0 MainWindow::openLog mainwindow.cpp 147
1 NewLog::createLog newlog.cpp 51
2 NewLog::qt_metacall moc_newlog.cpp 66
3 QMetaObject::activate qobject.cpp 3104
4 QMetaObject::activate qobject.cpp 3198
5 QAbstractButton::clicked moc_qabstractbutton.cpp 200
6 QAbstractButtonPrivate::emitClicked qabstractbutton.cpp 543
7 QAbstractButtonPrivate::click qabstractbutton.cpp 536
8 QAbstractButton::mouseReleaseEvent qabstractbutton.cpp 1115
9 QWidget::event qwidget.cpp 7554
10 QAbstractButton::event qabstractbutton.cpp 1077
11 QPushButton::event qpushbutton.cpp 662
12 QApplicationPrivate::notify_helper qapplication.cpp 4065
13 QApplication::notify qapplication.cpp 3767
14 QCoreApplication::notifyInternal qcoreapplication.cpp 610
15 QCoreApplication::sendSpontaneousEvent qcoreapplication.h 216
16 QApplicationPrivate::sendMouseEvent qapplication.cpp 2924
17 QETWidget::translateMouseEvent qapplication_win.cpp 3268
18 QtWndProc qapplication_win.cpp 1667
19 USER32!GetDC C:\WINDOWS\system32\user32.dll 0
20 ?? 0
21 ?? 0
22 ?? 0

Is this what you meant?

tangential
23rd December 2009, 02:30
Definitely. Now that you have a line number, you should have a particular line of code that's falling over. Can you paste line 147 for us? (any variables used, their values? screenshot at the crash point, maybe?) :)

waynew
23rd December 2009, 03:03
Well here is the failing line. I could tell that because when I comment it out (and the next line for the view), no crash.



delete model;


and probably delete view; would do it too. That is the next line.

But, as you rightly pointed out earlier and my research confirmed, delete <pointer> checks for null before it deletes. I don't think that is the problem since I have tested it with a 'model' open and it still crashes when called from the dialog. So in that case, I know model was not null (the current view was open and displaying data from the model and the model was created on the heap).
.
Interestingly, when I put a lineEdit and a button on the main form to call the same function (mimic the dialog action), it always works perfectly. It only crashes when I try to do this function from the dialog. You can see the dialog call code above. I'm thinking it must have something to do with being able to reference the model properly from the mainwindow form, but not when the function is called from the dialog, which is called from the mainwindow menu.

What I don't understand is the difference.

Here is the code that gets called when it crashes:


void MainWindow::openLog(QString logName) {
qDebug() << "logName is " << logName;
delete model;
delete view;
// etc....


I'll try screen shots tomorrow - have to load SnagIt first.
Thanks for your help!

tangential
23rd December 2009, 06:47
Just a shot in the dark here, but have you tried either setModel(NULL) on the view before you delete it, or flipping the deletion of the model and view objects? The view may be referencing the model object, and not yet be getting the deletion notification from the model, and then goes on to try and dereference it. It's a longshot, but, it may just work.

waynew
24th December 2009, 00:53
Sorry Tangential, neither of those suggestions had any effect.
Nothing useful in screenshots - just the usual - Do you want to debug with QtCreator?, etc.

I still feel something is different when the function containing the view and model delete is called from the mainwindow (works) and the dialog (fails).
It's like the reference to the view/model is lost when the dialog opens, but then I'm a newbie, so I don't really know and don't know how to tell.
But if delete really does check for null first, I guess it shouldn't matter?

I have coded around the problem for the moment by putting a lineEdit and a pb on the mainwindow. Maybe I will figure it out some day.

waynew
24th December 2009, 01:17
Another thought - I don't know if this is related or not but seems like it could be.

I have another dialog that uses a pb to call a dialog function via a signal/slot.
The slot function then saves a new database value.
When the dialog closes, the mainwindow updateStats() is called.
In updateStats, debug shows the new value to display, but it is never displayed. It's like the mainwindow never gets refreshed.

Maybe there is something fundamentally wrong with my mainwindow design so that is acting like it is disconnected from my dialogs???