Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

QT App crashes Part 2

Posted on 2011-10-23
6
Medium Priority
?
320 Views
Last Modified: 2012-05-12
Hello:
I have the following code that generates the following User Interface the UIBasically 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.
/// mytable.h
# 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

Open in new window


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);
		}
	}
}

Open in new window


This is the code that uses myTable. It is myDialog.h

# 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
]

Open in new window


And this is the corresponding myDialog.cpp file.
# include "myDialog.h"
# include <QVBoxLayout>

myDialog::myDialog()
{
	this->mTable = new myTable();
	this->mTable->show();
	this->mAddButton = new QPushButton("Add Row");
        this->mRemoveButton = new QPushButton("Remove Row");
	this->mAddButton->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();
};

Open in new window


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.
0
Comment
Question by:arjoshi77
  • 3
  • 3
6 Comments
 

Author Comment

by:arjoshi77
ID: 37013969
the behavior I expect from the above is that AddRow should adda new row. And removeRow should remove the rows which have their checkboxes selected.
0
 
LVL 35

Accepted Solution

by:
sarabande earned 2000 total points
ID: 37016695
the crash happens cause removeRow will shrink the list of rows. the index i running from 0 to num_rows-1 will be out-of-boundary when the half of rows was removed.

you should always call removeRow(0) in the loop. that should solve the problem.

Sara
0
 
LVL 35

Expert Comment

by:sarabande
ID: 37016699
another way is to remove rows from end to begin.

Sara
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:arjoshi77
ID: 37017463
sara : thanks for pointing me in the right direction. I inserted the following line in the loop ( see code below). and it worked !! Thanks a gazillion.

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);
				numRows = this->rowCount(); //THIS LINE I INSERTED
		}
	}
}

Open in new window

0
 

Author Closing Comment

by:arjoshi77
ID: 37017465
Thnks very very much.
0
 
LVL 35

Expert Comment

by:sarabande
ID: 37017640
that only will work if the user never checks two or more rows. the second remove would remove on wrong index because of the first removal.

if you run the loop backwards it always will work.

for ( int i = numRows-1 ; i >= 0; i--)

Open in new window


Sara
0

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction This article is the first in a series of articles about the C/C++ Visual Studio Express debugger.  It provides a quick start guide in using the debugger. Part 2 focuses on additional topics in breakpoints.  Lastly, Part 3 focuses on th…
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.
Suggested Courses

810 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question