PDA

View Full Version : Must all cellWidgets in a QTable be the same widget type?



davethomaspilot
9th January 2013, 16:58
I have a QTableWidget with QComboBoxs in row 0. External events will trigger changes to row zero--I was going to copy row 0 using the data associated with each comboboxes currentItem into a new row in the table.

Right now, I get the QTable created with row 0 having the ComboBoxes. I can addItems for each combobox when the external event occurs with no issues.

However, I wanted one of the columns to NOT have a QComboBox, but just a regular cell. But, when I don't do a setCellWidget on column 0, I get an exception when trying to add an item to the column 1 combobox.

I tried using a QLabel for the cell widget for the column 0, row 0 cell and have the same problem.

Is this expected? Maybe if one cell has a widget, all cells in the table must use the same widget?

Here are the relevant code snippets.

In constructor:




// No widget desired in column 0
runOrder->setItem(0,0, new QTableWidgetItem);
//runOrder->setCellWidget(0,0,new QLabel);

// Comboboxes in columns 1 through seven of row 0
for (int i=1;i<7;i++)
{
QComboBox *qb = new QComboBox;
runOrder->setItem(0,i, new QTableWidgetItem);
runOrder->setCellWidget(0,i, qb);
connect(qb, SIGNAL(currentIndexChanged(int)), this,SLOT(check_lineup(int)));

}


// Comboboxes in columns 1 through seven of row 0, not column 0
for (int i=1;i<7;i++)
{
QComboBox *qb = new QComboBox;
runOrder->setItem(0,i, new QTableWidgetItem);
runOrder->setCellWidget(0,i, qb);
connect(qb, SIGNAL(currentIndexChanged(int)), this,SLOT(check_lineup(int)));

}

In the code that adds entries to the comboboxes:


//Loop through the columns of row zero that have comboBoxes

for (int i=1;i<5;i++)
{
QComboBox * qb = dynamic_cast<QComboBox *>(runOrder->cellWidget(0,i));
qb->clear();
//Loop through the lineup
for (int j=0;j<5;j++)
{
QString dog_name= lineup_query.value(j).toString();
qb->addItem(dog_name);
}
qb->setCurrentIndex(i);

}

If I change

// Comboboxes in columns 1 through seven of row 0
for (int i=1;i<7;i++)
{
QComboBox *qb = new QComboBox;
runOrder->setItem(0,i, new QTableWidgetItem);
runOrder->setCellWidget(0,i, qb);
connect(qb, SIGNAL(currentIndexChanged(int)), this,SLOT(check_lineup(int)));

}

to loop from 0 to 7, everything seems to work fine, except I get a comboBox in column zero I really don't want.

Thanks,

Dave Thomas

wysota
9th January 2013, 17:18
Cell widgets can be of any type. I suggest you check the return value of dynamic_cast before trying to dereference the received pointer.

davethomaspilot
9th January 2013, 17:47
The pointer returned from the dynamic_cast is not Null.

Here's what it looks like:

8569
Also, note the line:


qb->clear();

Doesn't raise and excpetion

wysota
9th January 2013, 17:54
If it's not null then there is a combobox there. Where does the code crash? Show us the backtrace.

davethomaspilot
9th January 2013, 18:21
It looks like the crash is occuring in a slot that got called as a result of an item change in the QComboBox. Here's my method for the slot:



void CollectStats::check_lineup(int n)
{
QComboBox *changed_cell= dynamic_cast<QComboBox *>(sender());
changed_cell->setStyleSheet("QComboBox { background-color: white;font:16pt }");
for (int i=0;i<6;i++)
{

QComboBox *qp = dynamic_cast<QComboBox *>(runOrder->cellWidget(0,i));
if (sender() ==qp) continue;
if (qp->currentIndex()==n)
qp->setStyleSheet("QComboBox { background-color: red; font:16pt }");
else
qp->setStyleSheet("QComboBox { background-color: white; font:16pt }");

}

}


It looks like it's dying on the


if (qp->currentIndex()==n)

I'm not sure how to print the stack trace from VS, so here are a couple of screen shots:
85708571

Thanks for the attention!

Found it,

Should be

for (int i=1;i<7;i++)

In the check_lineup method, after I eliminated the combobox in column 0.

I feel stupid, thanks for your extremely fast replies--it got me pointed in the right direction!

Dave Thomas