PDA

View Full Version : Add a new row to QTableWidget with initialized cells cause to segmentation fault



SIFE
17th January 2012, 16:34
I have this slot:

void MainWindow::addRow()
{
int rows = ui->tableWidget->rowCount();
ui->tableWidget->insertRow(rows);
QTableWidgetItem *item;
item = new QTableWidgetItem;
item->setText(QString::number(0, 'f', 2));
ui->tableWidget->setItem(rows - 1, 1, item);
item = new QTableWidgetItem;
item->setText(QString::number(0, 'f', 2));
ui->tableWidget->setItem(rows - 1, 2, item);
}
When I add a new row, I get a segmentation fault, why?

Lykurg
17th January 2012, 16:51
ui->tableWidget->setItem(rows - 1, 1, item);
// [..]
ui->tableWidget->setItem(rows - 1, 2, item);

Musn't that be
ui->tableWidget->setItem(rows - 1, 0, item);
// [..]
ui->tableWidget->setItem(rows - 1, 1, item);

And use a debugger to see where exactly the application crashes.

SIFE
17th January 2012, 17:11
I tried this:


item = new QTableWidgetItem;
item->setText(QString::number(0, 'f', 2));
ui->tableWidget->setItem(rows, 0, item);
/*item = new QTableWidgetItem;
item->setText(QString::number(0, 'f', 2));
ui->tableWidget->setItem(rows, 1, item);*/
This make first column initialized, but I need only the second and third columns to be initialized.

And use a debugger to see where exactly the application crashes.
Debugger didn't work with me in FreeBSD.

Lykurg
17th January 2012, 18:08
And you are using
ui->tableWidget->setItem(rows, 0, item); or
ui->tableWidget->setItem(rows-1, 0, item);? And if you don't use a debugger, what makes you sure this slot is causing the trouble? Comment all out and add it one by one to see where the crash happens.

SIFE
17th January 2012, 20:44
It 's appear like another slot cause the problem:


//connected signals
connect(ui->tableWidget, SIGNAL(cellChanged(int,int)), this, SLOT(calc(int,int)));


void MainWindow::calc(int x,int y)
{
if (y == 1)
{
float ttl = ui->tableWidget->item(x, y)->data(0).toFloat() * ui->tableWidget->item(x, 2)->data(0).toFloat();
QTableWidgetItem *item = new QTableWidgetItem;
item->setText(QString::number(ttl, 'f', 2));
ui->tableWidget->setItem(x, 3, item);
ttl = 0;
int rows = ui->tableWidget->rowCount();
for (int i = 0; i < rows; ++i)
{
ttl += ui->tableWidget->item(i, 3)->data(0).toFloat();
}

ui->totaleEdit->setText(QString::number(ttl, 'r', 2));
}
else if (y == 2)
{
float ttl = ui->tableWidget->item(x, y)->data(0).toFloat() * ui->tableWidget->item(x, 1)->data(0).toFloat();
QTableWidgetItem *item = new QTableWidgetItem;
item->setText(QString::number(ttl, 'f', 2));
ui->tableWidget->setItem(x, 3, item);
ttl = 0;
int rows = ui->tableWidget->rowCount();
for (int i = 0; i < rows; ++i)
{
ttl += ui->tableWidget->item(i, 3)->data(0).toFloat();
}

ui->totaleEdit->setText(QString::number(ttl, 'r', 2));
}
}
So, I cheated with this condition:

if (y == 1 && ui->tableWidget->item(x, y)->data(0).toString() == "")

Lykurg
17th January 2012, 22:12
That's why a debugger is a good choice! Your code look also hard to maintain... and
ttl = 0;
int rows = ui->tableWidget->rowCount();
for (int i = 0; i < rows; ++i)
{
ttl += ui->tableWidget->item(i, 3)->data(0).toFloat();
}

ui->totaleEdit->setText(QString::number(ttl, 'r', 2));is madness for large tables. Better store the old value of (x,3) and calc the difference and only add/substract that from ui->totaleEdit.