Crash: using a dialog in a model
I am getting some strange behavior that has me stumped. An otherwise working model/view/delegate program will crash if a static dialog is used within the Method::setData() or Delegate::setModelData() methods. The program will pop up two dialogs, then segfault when both are closed.
I am trying to use a QMessageBox::warning() when the user enters invalid data. This is something the program needs to do. I get the same behavior with other static dialogs (QColorDialog, etc). It happens with both QTableView and QListView. The double dialog and crash happens when the user presses the enter or tab keys when finished editing in the delegate. It does NOT happen if the user clicks elsewhere in the view to finish editing.
I have created a tiny sample program to demonstrate. It's as short as I can get it with both a model and delegate. Remove the QMessageBox dialog and the program works. Keep it in and watch the strangeness when you edit a value.
Code:
#include <QtGui>
Q_OBJECT
public:
~TestModel();
int role = Qt::EditRole);
private:
};
{
Q_OBJECT
public:
~TestDelegate();
void updateEditorGeometry
(QWidget *editor,
};
Code:
#include <QtGui>
#include "model.h"
{
items << "one" << "two" << "three" << "four";
}
TestModel::~TestModel() {}
{
if (!index.
isValid()) return QVariant();
if (index.
row() >
= items.
count()) return QVariant();
if ((role == Qt::DisplayRole) || (role == Qt::EditRole)) {
return items[index.row()];
} else {
}
}
{
if (!index.isValid()) return false;
if (index.row() >= items.count()) return false;
if (role != Qt::EditRole) return false;
items[index.row()] = value.toString();
emit dataChanged(index, index);
return true;
}
Qt
::ItemFlags TestModel
::flags(const QModelIndex &index
) const{
if (!index.isValid()) return Qt::ItemIsEnabled;
}
{
return items.count();
}
{
return 1;
}
TestDelegate::~TestDelegate() {}
{
items << "one" <<"two" <<"three" <<"four";
edit->installEventFilter(const_cast<TestDelegate*>(this));
return edit;
}
void TestDelegate
::setEditorData(QWidget *editor,
{
QVariant value
= index.
model()->data
(index, Qt
::EditRole);
QLineEdit *edit
=static_cast<QLineEdit
*>
(editor
);
if (!edit) return;
edit->setText(value.toString());
}
{
QLineEdit *edit
= static_cast<QLineEdit
*>
(editor
);
if (!edit) return;
model->setData(index, value);
}
void TestDelegate
::updateEditorGeometry(QWidget *editor,
{
if (editor) editor->setGeometry(option.rect);
}
Code:
#include <QtGui>
#include "model.h"
int main(int argc, char *argv[])
{
TestModel model(0);
view.setModel(&model);
TestDelegate delegate;
view.setItemDelegate(&delegate);
view.show();
return app.exec();
}
I am using qt-4.1.2 on FreeBSD 6.0. I am going to submit this a bug to Trolltech as well, as I've not found anything similar in their tracker.
Re: Crash: using a dialog in a model
Apart from anything else... you are violating the model-view-delegate separation. You shouldn't be asking any questions or displaying any dialogs in the "model part". You should confirm the data on the view or delegate level. What if you want to change the data in the model without confirmation or even without user's knowledge?
About the crash -- run your application under debugger and show us the stack trace you get.
Re: Crash: using a dialog in a model
Quote:
Originally Posted by wysota
Apart from anything else... you are violating the model-view-delegate separation. You shouldn't be asking any questions or displaying any dialogs in the "model part". You should confirm the data on the view or delegate level. What if you want to change the data in the model without confirmation or even without user's knowledge?
I have to validate the input in the model, because only the model has sufficient information to do so. All the delegate knows about is one particular index, and all the view knows about is what the model tells is through the standard model/view API. Only the model knows if the input is valid for the model.
But regardless, the crash happens when I pop up the dialog in the delegate instead, and even if I send a signal from the model to the view. You can't get better model/view separation than that! I can simply just reject the input, but that's rude to the user, who's left scratching his head as to why the delegate editor isn't working.
Re: Crash: using a dialog in a model
I got a reply from Trolltech. This is a known issue, bug #106260, which is fixed in the latest snapshot and will be in 4.1.3.