PDA

View Full Version : QTableWidget::clearContents() crashes if called after selecting items



rewt
12th November 2009, 17:44
I "hacked" the qt4/demos/spreadsheet example and put together a program that loads a specific form of a table from file. I got rid of all editing support, and use merely the functionality for highlighting by clicking with the mouse on items in the table. I use this as selection mechanism, and then have other functions read the selected items to do other processing. All of this works nicely, except when I then try to remove the currently loaded table and replace it by another one. It crashes when I call clearContents(), either directly or by emmiting a signal that is connected to the slot clearContents() in the existing base QTableWidget (inherited from some other Qt class).

This problem only occurs if I have actually selected an item in the table.

Using a file selection dialogue, I can load one table from file and display it, then load another one and display and so on. For each new load, clearContents() is called and then the new table is loaded. This works, but only if I never touch the table, never bring any of the items to highlight. Otherwise, as soon as clearContents() is called, the application crashes with segmentation fault.

Most likely I made a mistake somewhere but the question is where too look?

rewt
12th November 2009, 19:05
I guess I figured it out why this crashed: The callback updateStatus which was implemented as partially shown below, was still accessing items if they didn't even exist:

void SpreadSheet::updateStatus(QTableWidgetItem *item)
{
if (item && item == currentItem()) {
lastColumn = currentColumn();
lastLine = currentRow();
validSelection=true; // <----- prevents access of garbage later
if (lastColumn == SPCOL::lesseme || lastColumn == SPCOL::promptname) {
emit customSignalEdit( item->data(Qt::StatusTipRole).toString() );
}
}

if (!item || !validSelection) return; // <--- that fixed it
....
// remark: lastColumn and lastLine, as well as validSelection are protected variables in this class, which is derived from QTableWidget ()

Initially, calling the above with *item == NULL was not properly checked. It turned out that when a new table was displayed updateStatus was also called, even though nothing was selected.
However, just below the code shown here, I accessed the pointer *item without further checking. In that code the assumption was made that previously something had been selected. But that could not be the case for a new table, because I had forgotten to initialize properly some other variables when a new table was loaded.

At any rate, all's working now - you may move to other problems :-) - thanks to anyone who may have wasted any thoughts on this