PDA

View Full Version : QT application crashes.



coding_neo
24th October 2011, 08:27
Hello:
I have the following code that generates the following User Interface 7028
Basically its a QDIalog encapsualting 2 QPushButtons and a class derived from QTableWidget. The ADDROW button adds rows. Each row is comprised of 4 fielsd, a checkbox, a combobox and text for the remainder of the tqo. The corresponding code is spread out in the following 4 files.


# ifndef __MTBL__
# define __MTBL__

# include <QTableWidget>
# include <QPushButton>
# include <QComboBox>
# include <QDialog>
# include <QCheckBox>

class myTable : public QTableWidget
{
Q_OBJECT
public:
myTable();
public slots:
void addCustomRow();
void removeCustomRow();
};
# endif


This is the corresponding source file. myTable.cpp



# include "myTable.h"
# include <QMessageBox>

myTable::myTable()
{
this->setRowCount(0);
this->setColumnCount(4);
};

void myTable::addCustomRow()
{
int row = this->rowCount();
this->insertRow(row);
QMessageBox *q = new QMessageBox();
q->setText("here");
q->show();
QComboBox *mBox = new QComboBox();
mBox->show();
mBox->addItem("Hello");
mBox->addItem("World");
mBox->show();
QCheckBox *mCheck = new QCheckBox();
mCheck->setChecked(false);
mCheck->show();
this->setCellWidget(row,0,mCheck);
this->setCellWidget(row,1,mBox);
this->item(row,2)->setText("Delta " + QString(row));
this->item(row,3)->setText("Theta" + QString(row));
};

void myTable::removeCustomRow()
{
int numRows = this->rowCount();

for ( int i = 0 ; i < numRows ; i++)
{

QCheckBox* mBox = static_cast<QCheckBox*> (this->cellWidget(i,0));
QMessageBox::information(this,"removeCustomRow","code works till here");
if (mBox->isChecked())
{
this->removeRow(i);
}
}
}

This is the dialog file which encapsulates myTable and the two buttons.



# ifndef __MDLG__
# define __MDLG__
# include <QTableWidget>
# include <QPushButton>
# include <QComboBox>
# include <QDialog>
# include "myTable.h"

class myDialog : public QDialog
{
Q_OBJECT
public:
myTable * mTable;
QPushButton * mAddButton;
QPushButton * mRemoveButton;

myDialog();
};
# endif




# include "myDialog.h"
# include <QVBoxLayout>

myDialog::myDialog()
{
this->mTable = new myTable();
this->mTable->show();
this->mAddButton = new QPushButton("Add Row");
this->mAddButton->show();
this->mRemoveButton = new QPushButton("Remove Row");
this->mRemoveButton->show();

QVBoxLayout *mLay = new QVBoxLayout();

mLay->addWidget(this->mAddButton);
mLay->addWidget(this->mRemoveButton);
mLay->addWidget(this->mTable);
this->connect(this->mAddButton,SIGNAL(clicked()),this->mTable,SLOT(addCustomRow()));
this->connect(this->mRemoveButton,SIGNAL(clicked()),this->mTable,SLOT(removeCustomRow()));
this->setLayout(mLay);
this->show();
};



The problem is with the removeCustomRow () slot in myTable.cpp. Whenever I select a checkbox in the UI above and hit "Remove Row" button the application crashes. I put in debugging code and found that the loop in the removeCUstomRow () function tends to remove all the rows (even if they are not checked) and then crashes.
The above code is standalone so you can copy and paste it in you ide and see its behavior.

Just include the files and instantiate myDIalog between QApplication a(argc,argv) and app.exe and you will be able to replicate the problem at your end.
Any help would be appreciated.

stampede
24th October 2011, 08:53
You don't check the value of returned pointer:

QCheckBox* mBox = static_cast<QCheckBox*> (this->cellWidget(i,0));
QMessageBox::information(this,"removeCustomRow","code works till here");
if (mBox->isChecked())

what happens if mBox is NULL ? A crash.
btw. I'd rather use qobject_cast for casting between QObject-based pointers.

ChrisW67
24th October 2011, 09:53
Check the logic of your loop. You cache the row count (n) and then proceed to remove rows 0 through n-1. As soon as you remove row 0 the last row is no longer n-1 and the old row 1 becomes the new row 0. You then step on leaving row 0 and delete row 1. At about half way you will try to address a widget and remove a row that no longer exists.

coding_neo
24th October 2011, 14:30
chris:

Thanks. I made the relevant changes and now the code works.