Results 1 to 4 of 4

Thread: Crash: using a dialog in a model

  1. #1
    Join Date
    Mar 2006
    Location
    Mountain View, California
    Posts
    489
    Thanks
    3
    Thanked 74 Times in 54 Posts
    Qt products
    Qt3 Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Unhappy 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.

    Qt Code:
    1. #include <QtGui>
    2.  
    3. class TestModel : public QAbstractTableModel {
    4. Q_OBJECT
    5. public:
    6. TestModel(QObject *parent);
    7. ~TestModel();
    8.  
    9. QVariant data(const QModelIndex &index, int role) const;
    10. bool setData(const QModelIndex &index, const QVariant &value,
    11. int role = Qt::EditRole);
    12. Qt::ItemFlags flags(const QModelIndex &index) const;
    13. int rowCount(const QModelIndex &parent = QModelIndex()) const;
    14. int columnCount(const QModelIndex &parent = QModelIndex()) const;
    15.  
    16. private:
    17. QStringList items;
    18. };
    19.  
    20. class TestDelegate : public QItemDelegate
    21. {
    22. Q_OBJECT
    23. public:
    24. TestDelegate(QObject *parent = 0);
    25. ~TestDelegate();
    26.  
    27. QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
    28. const QModelIndex &index) const;
    29. void setEditorData(QWidget *editor, const QModelIndex &index) const;
    30. void setModelData(QWidget *editor, QAbstractItemModel *model,
    31. const QModelIndex &index) const;
    32. void updateEditorGeometry(QWidget *editor,
    33. const QStyleOptionViewItem &option,
    34. const QModelIndex &index) const;
    35. };
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. #include <QtGui>
    2. #include "model.h"
    3.  
    4. TestModel::TestModel(QObject *parent) : QAbstractTableModel(parent)
    5. {
    6. items << "one" << "two" << "three" << "four";
    7. }
    8.  
    9. TestModel::~TestModel() {}
    10.  
    11. QVariant TestModel::data(const QModelIndex &index, int role) const
    12. {
    13. if (!index.isValid()) return QVariant();
    14. if (index.row() >= items.count()) return QVariant();
    15.  
    16. if ((role == Qt::DisplayRole) || (role == Qt::EditRole)) {
    17. return items[index.row()];
    18. } else {
    19. return QVariant();
    20. }
    21. }
    22.  
    23. bool TestModel::setData(const QModelIndex &index,
    24. const QVariant &value, int role)
    25. {
    26. if (!index.isValid()) return false;
    27. if (index.row() >= items.count()) return false;
    28. if (role != Qt::EditRole) return false;
    29.  
    30. QMessageBox::information(0, "Test", "This is a test");
    31.  
    32. items[index.row()] = value.toString();
    33.  
    34. emit dataChanged(index, index);
    35. return true;
    36. }
    37.  
    38. Qt::ItemFlags TestModel::flags(const QModelIndex &index) const
    39. {
    40. if (!index.isValid()) return Qt::ItemIsEnabled;
    41. return QAbstractTableModel::flags(index) | Qt::ItemIsEditable;
    42. }
    43.  
    44. int TestModel::rowCount(const QModelIndex &) const
    45. {
    46. return items.count();
    47. }
    48.  
    49. int TestModel::columnCount(const QModelIndex &) const
    50. {
    51. return 1;
    52. }
    53.  
    54. TestDelegate::TestDelegate(QObject *parent) : QItemDelegate(parent) {}
    55.  
    56. TestDelegate::~TestDelegate() {}
    57.  
    58. QWidget *TestDelegate::createEditor(QWidget *parent,
    59. const QStyleOptionViewItem &/*option*/,
    60. const QModelIndex &index) const
    61. {
    62. QStringList items;
    63. items << "one" <<"two" <<"three" <<"four";
    64.  
    65. QLineEdit *edit = new QLineEdit(parent);
    66. edit->installEventFilter(const_cast<TestDelegate*>(this));
    67. return edit;
    68. }
    69.  
    70. void TestDelegate::setEditorData(QWidget *editor,
    71. const QModelIndex &index) const
    72. {
    73. QVariant value = index.model()->data(index, Qt::EditRole);
    74.  
    75. QLineEdit *edit =static_cast<QLineEdit*>(editor);
    76. if (!edit) return;
    77. edit->setText(value.toString());
    78. }
    79.  
    80. void TestDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
    81. const QModelIndex &index) const
    82. {
    83. QLineEdit *edit = static_cast<QLineEdit*>(editor);
    84. if (!edit) return;
    85. QVariant value = edit->text();
    86. model->setData(index, value);
    87.  
    88. }
    89.  
    90. void TestDelegate::updateEditorGeometry(QWidget *editor,
    91. const QStyleOptionViewItem &option,
    92. const QModelIndex &/*index*/) const
    93. {
    94. if (editor) editor->setGeometry(option.rect);
    95. }
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. #include <QtGui>
    2. #include "model.h"
    3.  
    4. int main(int argc, char *argv[])
    5. {
    6. QApplication app(argc, argv);
    7.  
    8. TestModel model(0);
    9.  
    10. QTableView view;
    11. view.setModel(&model);
    12.  
    13. TestDelegate delegate;
    14. view.setItemDelegate(&delegate);
    15.  
    16. view.show();
    17. return app.exec();
    18. }
    To copy to clipboard, switch view to plain text mode 

    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.

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default 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.

  3. #3
    Join Date
    Mar 2006
    Location
    Mountain View, California
    Posts
    489
    Thanks
    3
    Thanked 74 Times in 54 Posts
    Qt products
    Qt3 Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default 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.

  4. #4
    Join Date
    Mar 2006
    Location
    Mountain View, California
    Posts
    489
    Thanks
    3
    Thanked 74 Times in 54 Posts
    Qt products
    Qt3 Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default 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.

Similar Threads

  1. hierarchical model in a flat view
    By gniking in forum Qt Programming
    Replies: 4
    Last Post: 10th November 2009, 20:17
  2. A few queries about Model View Programming
    By montylee in forum Qt Programming
    Replies: 46
    Last Post: 2nd March 2009, 08:36
  3. Issue with Modelless dialog on Mac
    By Satyanarayana Chebrolu in forum Qt Programming
    Replies: 0
    Last Post: 24th February 2009, 10:10
  4. Resizing the dialog boxes
    By anju123 in forum Qt Programming
    Replies: 4
    Last Post: 14th September 2007, 10:41
  5. dialog box
    By Bahar in forum Qt Programming
    Replies: 3
    Last Post: 31st January 2006, 14:52

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.