PDA

View Full Version : Simple program segfaults. QListView? Out of ideas.



rpocnab
1st April 2011, 00:27
I'm making a program to present the user (me) with a list of filenames and the option to do a few things to them. But I'm still only at the point of just testing how QListView works. It ought to be really simple, but it's crashing and I'm stuck.

I don't even know where exactly it crashes; it's after the app exec(). I think maybe some object is being destroyed, and later accessed, but I don't understand Qt very well. As for some guesses: I read that QListView doesn't take ownership of models, but it still crashes if QStringListModel is initialized with any parent. I'm not using QModelIndex yet so it can't be due do to sloppy use of one of those.

The program happens to segfault in QTextEngine's itemize(). It won't crash if some statements are switched around, or if the strings have very slightly different contents, or if a messagebox is exec() before dialog.show(), etc. However, I assume those are coincidences related to how memory is laid out, or timing.

What am I doing wrong? I'm out of ideas.

It's Qt 4.7.0 on linux. Problem also happens with Qt 4.7.2.



#include <QtGui>
#include <QtGlobal>

int main(int argc, char *argv[])
{
QApplication a(argc, argv);

QDialog dialog;
QVBoxLayout layout;
QLabel label("label of stuff");
QListView view;
QStringListModel model;
QStringList list;

list.append(QString("hello"));
list.append(QString("The cat he"));
model.setStringList(list);
view.setModel(&model);

dialog.setLayout(&layout);
layout.addWidget(&label);
dialog.show(); // if this happens here it crashes
layout.addWidget(&view);

//dialog.show(); // if this instead happens here it's "stable"

return a.exec();
}

stampede
1st April 2011, 08:04
No crash on my machine. You should rather create your widgets on a heap ( with operator new ), try it and see if it still crashes:


#include <QtGui>
#include <QtGlobal>

int main(int argc, char *argv[])
{
QApplication a(argc, argv);

QDialog * dialog = new QDialog();
QVBoxLayout * layout = new QVboxLayout(dialog);
QLabel * label = new QLabel("label of stuff",dialog);
QListView * view = new QListView(dialog);
QStringListModel * model = new QStringListModel(view);
QStringList list;

list.append(QString("hello"));
list.append(QString("The cat he"));
model->setStringList(list);
view->setModel(model);

dialog->setLayout(layout);
layout->addWidget(label);
dialog->show();
layout->addWidget(view);

int res = a.exec();

delete dialog;

return res;
}

rpocnab
1st April 2011, 23:09
No luck, but thanks anyway. I wonder how smart it would be to use the program in one of the configurations that doesn't crash, but knowing it might be very close to doing so.

I made a version that connected every QObject's destroyed() signal to a message box's exec(), and the message box never appeared. So I don't think it's a bad pointer anymore.

Zlatomir
1st April 2011, 23:33
Why would you like to add to the layout after the widget is after the dialog is shown?
In your particular case everything will happen so fast you won't see the "empty" dialog anyway.

If you really need to show half of the dialog and the rest sometime after, you can add all the widgets to layout and specifically hide the ones you don't want and then show them later.

And follow stampede's advice and create widgets on the heap.

//your code doesn't crash on Windows with Qt 4.7.2 - i can't test on Linux at the moment

rpocnab
1st April 2011, 23:44
I didn't think the order would make a difference, and once I saw it could crash I wanted to know why. However, now I can see the order affects how the dialog is sized.