June 30, 2011

brucewuu brucewuu
Lab Rat
49 posts

QTableView::setModel(NULL) crash application ???

 

hi guys , I have QTableView crashing , the code is like this

  1. QAbstractItemModel* model = tableView()->model();
  2. tableView()->setModel( NULL );

when I debug , it crashed when setModel(NULL) runs , and it said
ASSERT:“visualRow != -1” in file itemviews\qtableview.cpp ,
and I found it strange that if I don’t modify the data from tableview , then it won’t crash when I debug here
while if I modify the data from tableview , it will crash here , is this a qt bug or my code’s bug . someone could
give me some good suggestions , thank you very much ~~

EDIT: please use @-tags for code highlighting, Gerolf

 Signature 

wish all the best to you from
bruce wuu
Autodesk China Inc.
SW Developer
M&E Product Developerment Group
Work 137 6411 8921
.(JavaScript must be enabled to view this email address)

10 replies

June 30, 2011

Volker Volker
Ant Farmer
5428 posts

I don’t understand your problem. If you set the model to NULL then there is nothing to be modified. If you do it nontheless, it’s no surprise that your app crashes.

June 30, 2011

peppe peppe
Ant Farmer
1029 posts

It’s not supposed to crash. Please make a complete testcase.

 Signature 

Software Engineer
KDAB (UK) Ltd., a KDAB Group company

July 1, 2011

brucewuu brucewuu
Lab Rat
49 posts

but when I debug it , it crash at the setModel(NULL) and assert “visualRow != -1” , does this mean before I setModel(NULL) , I should hide all rows in tableView , if I don’t hide , it will crash , do you have met such situations ?

 Signature 

wish all the best to you from
bruce wuu
Autodesk China Inc.
SW Developer
M&E Product Developerment Group
Work 137 6411 8921
.(JavaScript must be enabled to view this email address)

July 1, 2011

Volker Volker
Ant Farmer
5428 posts

I cannot reproduce this. Further investigation is not possible with your very tiny code snippets.

The following code works perfectly for me:

————— nullmodeltest.h —————

  1. #ifndef NULLMODELTEST_H
  2. #define NULLMODELTEST_H
  3.  
  4. #include <QWidget>
  5.  
  6. class QTableView;
  7. class QStandardItemModel;
  8. class QPushButton;
  9.  
  10. class NullModelTest : public QWidget
  11. {
  12.     Q_OBJECT
  13. public:
  14.     explicit NullModelTest(QWidget *parent = 0);
  15.  
  16. public slots:
  17.     void changeModel();
  18.  
  19. protected:
  20.     QTableView *view;
  21.     QStandardItemModel *model;
  22.     QPushButton *button;
  23. };
  24.  
  25. #endif // NULLMODELTEST_H

————— nullmodeltest.cpp —————

  1. #include "nullmodeltest.h"
  2. #include <QLayout>
  3. #include <QTableView>
  4. #include <QStandardItemModel>
  5. #include <QPushButton>
  6. #include <QDebug>
  7.  
  8. NullModelTest::NullModelTest(QWidget *parent) :
  9.     QWidget(parent)
  10. {
  11.     QVBoxLayout *lay = new QVBoxLayout(this);
  12.     view = new QTableView;
  13.     lay->addWidget(view);
  14.  
  15.     button = new QPushButton;
  16.     button->setText("change model");
  17.     lay->addWidget(button);
  18.  
  19.     connect(button, SIGNAL(clicked()), this, SLOT(changeModel()));
  20.  
  21.     int numRows = 5;
  22.     int numCols = 4;
  23.     model = new QStandardItemModel(numRows, numCols, this);
  24.     for(int r = 0; r < numRows; ++r)
  25.         for(int c = 0; c < numCols; ++c)
  26.             model->setItem(r, c, new QStandardItem(QString("cell %1/%2").arg(r).arg(c)));
  27.  
  28.     view->setModel(model);
  29. }
  30.  
  31.  
  32. void NullModelTest::changeModel()
  33. {
  34.     qDebug() << "NullModelTest::changeModel() ----- triggered -----";
  35.     qDebug() << "NullModelTest::changeModel(): old model=" << view->model();
  36.     if(view->model())
  37.         view->setModel(0);
  38.     else
  39.         view->setModel(model);
  40.     qDebug() << "NullModelTest::changeModel(): new model=" << view->model();
  41. }

————— main.cpp —————

  1. #include <QApplication>
  2. #include "nullmodeltest.h"
  3.  
  4. int main(int argc, char *argv[])
  5. {
  6.     QApplication a(argc, argv);
  7.  
  8.     NullModelTest nmt;
  9.     nmt.show();
  10.  
  11.     return a.exec();
  12. }

July 3, 2011

brucewuu brucewuu
Lab Rat
49 posts

thanks , Volker , I also did the simple testing like you , it won’t crash , in the project , it involves a lot of other code , like delegates , a little complicated , but when I debug the crash , it crash at the setModel(NULL), and I didn’t find where the other code crashed , I will pay more time on it , thanks very much ~~

 Signature 

wish all the best to you from
bruce wuu
Autodesk China Inc.
SW Developer
M&E Product Developerment Group
Work 137 6411 8921
.(JavaScript must be enabled to view this email address)

July 4, 2011

Volker Volker
Ant Farmer
5428 posts
brucewuu wrote:
thanks , Volker , I also did the simple testing like you , it won’t crash , in the project , it involves a lot of other code , like delegates , a little complicated , but when I debug the crash , it crash at the setModel(NULL), and I didn’t find where the other code crashed , I will pay more time on it , thanks very much ~~

So it is time to create a

  • short
  • complete
  • compilable

example for us that demonstrates the problem. Our crystal balls are on summer vacation, so unfortunately, we cannot guess what’s going wrong…

Oh, and experience tells us that your chances are good to find the mistake yourself while preparing the example :-)

July 4, 2011

brucewuu brucewuu
Lab Rat
49 posts

thanks , Volker , I will try to find the problem ~~

 Signature 

wish all the best to you from
bruce wuu
Autodesk China Inc.
SW Developer
M&E Product Developerment Group
Work 137 6411 8921
.(JavaScript must be enabled to view this email address)

September 23, 2012

JCipriani JCipriani
Lab Rat
23 posts

I’m having the same issue. setModel(NULL) crashes with:

ASSERT: “visualRow != -1” in file itemviews\qtableview.cpp, line 1568

It seems to crash if setModel(NULL) is called while an item in the table view is being edited.

I don’t know much more about it right now. I found this thread while trying to find info about the problem.

Qt 4.8 on Windows 7

September 24, 2012

JCipriani JCipriani
Lab Rat
23 posts

I made a test case and can consistently reproduce the problem. It happens when the following conditions (at least) are true:

1. The table is in edit mode (e.g. you are typing text in a cell and have not accepted the changes yet).
2. setModel(NULL) is called from the mousePressed event of another control.

It does not happen when setModel(NULL) is called from the clicked() signal of a push button.

Please let me know if I should start a new thread for this, and I will repost this there.

Here is a program that shows the problem. Click the table cell to begin editing it, and while it is being edited, click inside the frame on the right to crash the program (start an empty Qt project, create an empty cpp file and paste this all in there):

main.cpp

  1. #include <QtGui/QApplication>
  2. #include <QMainWindow>
  3. #include <QTableView>
  4. #include <QHBoxLayout>
  5. #include <QAbstractTableModel>
  6.  
  7.  
  8. class TestModel : public QAbstractTableModel {
  9. public:
  10.  
  11.     explicit TestModel (QWidget *parent) :
  12.         QAbstractTableModel(parent),
  13.         value_("Edit Me")
  14.     {
  15.     }
  16.  
  17.     int rowCount (const QModelIndex &parent) const {
  18.         return parent.isValid() ? 0 : 1;
  19.     }
  20.  
  21.     int columnCount (const QModelIndex &parent) const {
  22.         return parent.isValid() ? 0 : 1;
  23.     }
  24.  
  25.     Qt::ItemFlags flags (const QModelIndex &index) const {
  26.         return Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable;
  27.     }
  28.  
  29.     QVariant data (const QModelIndex &index, int role) const {
  30.         return (role == Qt::DisplayRole || role == Qt::EditRole) ? QVariant(value_) : QVariant::Invalid;
  31.     }
  32.  
  33.     bool setData (const QModelIndex &index, const QVariant &value, int role) {
  34.         if (role == Qt::EditRole) {
  35.             value_ = value.toString();
  36.             dataChanged(index, index);
  37.             return true;
  38.         } else
  39.             return false;
  40.     }
  41.  
  42. private:
  43.  
  44.     QString value_;
  45.  
  46. };
  47.  
  48.  
  49. class NullModelMousePressedFrame : public QFrame {
  50.  
  51. public:
  52.  
  53.     explicit NullModelMousePressedFrame (QTableView *view) :
  54.         view_(view)
  55.     {
  56.     }
  57.  
  58.     void mousePressEvent (QMouseEvent *event) {
  59.         view_->setModel(NULL);
  60.     }
  61.  
  62. private:
  63.  
  64.     QTableView *view_;
  65.  
  66. };
  67.  
  68.  
  69. int main (int argc, char **argv) {
  70.  
  71.     QApplication app(argc, argv);
  72.  
  73.     QHBoxLayout *layout = new QHBoxLayout();
  74.  
  75.     QTableView *table = new QTableView();
  76.     table->setModel(new TestModel(table));
  77.     layout->addWidget(table);
  78.  
  79.     NullModelMousePressedFrame *frame = new NullModelMousePressedFrame(table);
  80.     frame->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
  81.     frame->setMinimumWidth(100);
  82.     frame->setMaximumWidth(100);
  83.     frame->setFrameShape(QFrame::StyledPanel);
  84.     frame->setFrameShadow(QFrame::Sunken);
  85.     layout->addWidget(frame);
  86.  
  87.     QMainWindow *window = new QMainWindow();
  88.     window->setCentralWidget(new QFrame());
  89.     window->centralWidget()->setLayout(layout);
  90.     window->setWindowTitle("Click blank area on right while editing table.");
  91.     window->show();
  92.  
  93.     return app.exec();
  94.  
  95. }

September 24, 2012

JCipriani JCipriani
Lab Rat
23 posts

A workaround is to call setFocus() in the mousePressEvent() before setting the model to NULL. Clearly some kind of issue with QTableView’s assumptions during / just before a focus change. This is also suggested by the fact that the assertion failure is in QTableView::moveCursor (http://qt.gitorious.org/qt/qt/blobs/4.7/src/gui/itemviews/qtableview.cpp line 1561, although that’s 4.7 not 4.8).

Anyways this makes the above example not crash:

  1.     void mousePressEvent (QMouseEvent *event) {
  2.         setFocus(); // workaround (must be *before* setModel)
  3.         view_->setModel(NULL);
  4.     }

 
  ‹‹ WaitForFinished() fires early      [SOLVED] Can’t catch event ››

You must log in to post a reply. Not a member yet? Register here!