PDA

View Full Version : QSqlTableModel issues in 4.8.1 vs. 4.7.4?



mtnbiker66
11th July 2012, 20:26
Good afternoon --

I was wondering if anyone has noticed in behavioral differences when using QSqlTableModels in 4.8.1 vs. 4.7.4? I recently upgraded my Mac and downloaded the 4.8.1 version of Qt and I'm noticing some squirrely things that I've verified don't occur in 4.7.4

I have a lot of models in my app with 4 of them mapped to combo boxes. 2 of them work fine, but with 2 of the others, while the data initially appears correct in the combo box, if I click on an "edit" button beside the CB, the first record is replaced with the current index of the value I'm editing. For instance with the CB that controls data displayed throughout the app this is what I'm seeing:

Initially
Rig One
Rig Two --> current index

After I click edit, which generates an QInputDialog which I cancel out of
1
Rig Two

If I choose to edit "1" and cancel, it changes to "0"

For the other CB that's acting weird the data I'm editing is the data that's replaced with the index, so editing the 5 item in the list changes from "Ladder" to "4" and this happens immediately upon the QInputDialog being displayed (I can see the CB change).


What I've noticed via debugging is that the value changes after the QInputDialog is generated. Initially when this problem appeared it was happening when I clicked any pushbutton widget but I seem to have eliminated that (don't really know how). It's also strange that the other two CBs are working fine and they're all defined (at least to my eyes) in the same manner.


//*****************
//* Rig Data... *
//*****************
rigmodel = new QSqlTableModel(this, sqldb.db);

rigmodel->setTable ("rig");
rigmodel->sort (1, Qt::AscendingOrder);
rigmodel->setEditStrategy (QSqlTableModel::OnManualSubmit);

rigmodel->select ();

//*********************************************
//* This is the UI for editing Rig data... *
//*********************************************
ui->RigAdminNameCB->setModel (rigmodel);
ui->RigAdminNameCB->setModelColumn (1);
ui->RigAdminNameCB->setCurrentIndex (0);

rigmapper = new QDataWidgetMapper(this);
rigmapper->setModel (rigmodel);

rigmapper->setSubmitPolicy(QDataWidgetMapper::AutoSubmit);
rigmapper->addMapping(ui->RigAdminNameCB, 1);
rigmapper->addMapping(ui->RigTypeDrillShipRB, 2);
rigmapper->addMapping(ui->RigLengthOverallLE, 3);
rigmapper->addMapping(ui->RigLengthOverallFtRB, 4);
rigmapper->addMapping(ui->RigLengthK2FLE, 5);
rigmapper->addMapping(ui->RigLengthK2FFtRB, 6);
rigmapper->setCurrentIndex(0);


//******************************
//* Simulation Data setup... *
//******************************
simulationmodel = new QSqlTableModel(this, sqldb.db);

simulationmodel->setTable ("simulation");
simulationmodel->sort (1, Qt::AscendingOrder);
simulationmodel->setEditStrategy (QSqlTableModel::OnManualSubmit);
simulationmodel->setFilter (QString("sim_rig_id = %1").arg(rig_id));

simulationmodel->select ();

//************************************************** *
//* This is the UI for editing Simulation data... *
//************************************************** *
ui->SimNameCB->setModel (simulationmodel);
ui->SimNameCB->setModelColumn (1);
ui->SimNameCB->setCurrentIndex (0);

simulationmapper = new QDataWidgetMapper(this);
simulationmapper->setModel (simulationmodel);

simulationmapper->setSubmitPolicy(QDataWidgetMapper::AutoSubmit);
simulationmapper->addMapping (ui->SimNameCB, 1);
simulationmapper->setCurrentIndex(0);


//**********************
//* Riser ID data... *
//**********************
riseridmodel = new QSqlTableModel(this, sqldb.db);

riseridmodel->setTable ("riser");
riseridmodel->sort (1, Qt::AscendingOrder);
riseridmodel->setEditStrategy (QSqlTableModel::OnManualSubmit);

riseridmodel->setFilter (QString("riser_rig_id = %1").arg(rig_id));

riseridmodel->select ();

//**********************************************
//* This is the UI for editing Riser data... *
//**********************************************
ui->RiserConfigCB->setModel (riseridmodel);
ui->RiserConfigCB->setModelColumn (1);

//************************************************** ***********
//* Find the Riser Model for the Simulation being displayed *
//* and set the current index to that record... *
//************************************************** ***********
for (riser_index = 0; riser_index < riseridmodel->rowCount ();
riser_index++)
{
record = riseridmodel->record(riser_index);
if (record.value ("riser_id").toInt () == sim_riser_id)
break;
}

ui->RiserConfigCB->setCurrentIndex (riser_index);

riseridmapper = new QDataWidgetMapper(this);
riseridmapper->setModel (riseridmodel);

riseridmapper->setSubmitPolicy(QDataWidgetMapper::AutoSubmit);
riseridmapper->addMapping (ui->RiserConfigCB, 1);
riseridmapper->setCurrentIndex (riser_index);


//***************************
//* Rig Inventory Data... *
//***************************
riginvmodel = new QSqlTableModel(this, sqldb.db);

riginvmodel->setTable ("riginv");
riginvmodel->sort (33, Qt::AscendingOrder);
riginvmodel->setEditStrategy (QSqlTableModel::OnManualSubmit);

riginvmodel->setFilter (QString("riginv_rig_id = %1").arg(rig_id));
riginvmodel->select ();

//**************************************************
//* This is the UI for editing Inventory data... *
//**************************************************
ui->EquipIDCB->setModel (riginvmodel);
ui->EquipIDCB->setModelColumn (33);
ui->EquipIDCB->setCurrentIndex (0);

riginvmapper = new QDataWidgetMapper(this);
riginvmapper->setModel (riginvmodel);

riginvmapper->setSubmitPolicy(QDataWidgetMapper::AutoSubmit);
riginvmapper->addMapping (ui->EquipIDCB, 33);

riginvmapper->setCurrentIndex(0);


Here is the code where the first CB goes south:



void MainWindow::on_EditRigAdminPB_clicked()
{
bool ok;
int current_index;

QString oldrig_name;
QString newrig_name;
QString message;
QSqlRecord rig_record;

current_index = ui->RigAdminNameCB->currentIndex ();
rig_record = rigmodel->record (current_index);
oldrig_name = rig_record.value("rig_name").toString();

//***********************************
//* Go get a name for this rig... *
//***********************************

// if I display the data from the model at this point it's fine...

message = "Enter a New Name for this Rig: " + oldrig_name;
newrig_name = QInputDialog::getText (this, "Rig Name Change",
message, QLineEdit::Normal, QString(), &ok);

if (ok && !newrig_name.isEmpty ())
{
if (dup_rig_name_check (newrig_name))
{
QMessageBox::warning (this, tr("Rig Name exists"),
tr("A Rig data set of this name "
"already exists. Please re-enter."));
}
else
{
rigmodel->setData (rigmodel->index (current_index, 1), newrig_name);
rigmodel->setData (rigmodel->index (current_index, 6), user);
rigmodel->setData (rigmodel->index (current_index, 7),
QDateTime::currentDateTime ());

emit set_save_flag();
}
}
}


I've verified that apps works correctly on 4.7.4 in both Windows 7 and Mac 10.7.4 , but has this problem in 4.8.1 on both Windows and Mac.

Anyone witness anything like this? As you can see, the code is pretty straight forward and the fact that it works in a different version of Qt leaves me scratching my head

Thanks!


Kodi




The Riser and Simulation models are the ones that work correctly -- the Rig and Rig Inventory are the ones that don't.

ChrisW67
11th July 2012, 23:16
What does the signal set_save_flag() trigger?

mtnbiker66
12th July 2012, 00:58
It enables a pushbutton for "saving" the data




void MainWindow::set_save_flag ()
{
ui->actionSave_All->setEnabled(true);

need_to_save_flag = true;
}



Also, if I output the model data via a qDebug statement before "if (ok && !newrig_name.isEmpty ())", I can see that the data has changed...


Kodi

ps - thanks for asking!

ChrisW67
12th July 2012, 01:47
If the data in the model has changed before line 25, i.e. before any setData() calls, then the problem is not in the code I can see.


Also, see if the issue is related to https://bugreports.qt-project.org/browse/QTBUG-10491 (it is not exactly this though)

mtnbiker66
12th July 2012, 18:46
I can see the data change at the same time the QInputdialog gets displayed.

Thanks for the link about the bug -- I searched thru the bug reports but came back with nothing before I made this post, but that sounds like a really good possibility. I think what I'll do is change my database table structure to put the displayed column being the first instead of the second and see what happens.

Thanks for the extra set of eyes -- I didn't think I was going crazy since it works in a previous Qt version.


Kodi


ed. I changed the combo box to point to the first column in DB table, and it appeared to take care of the problem because the values in the CB stayed constant, however looking at the raw data, the 2nd column in the table -- the field previously displayed -- showed the change was still taking place. The data changed from "Rig One" to "0".

mtnbiker66
18th July 2012, 19:54
Back and forth with Qt on this -- the official answer, bolding mine:

...The data widget mapper "detects" the change in the combo box and updates the model via QSqlTable::setData(). The model has edit strategy OnManualSubmit, so changes are not submitted to the database right away. However, the model does emit dataChanged() which is received by the combo box and the mapper in an undefined order. If the list in the combo box gets updated first, consider yourself lucky.

Another important point concerns the default item delegate used by the mapper. It links the mapped model column to the "currentIndex" property (row) of the combo box while one might expect it would use the "currentText". This is why you see the number 0 set in the model instead of the text at that index.

Rejecting as "invalid" because the reported behavior is actually correct. Arguably, the default behavior of the item delegate with a combobox is suboptimal, but it's not quite a bug and there are documented ways to get more useful behavior.

QTBUG-26501

mtnbiker66
19th July 2012, 00:50
turns out this is a bug: https://bugreports.qt-project.org/browse/QTBUG-26501