PDA

View Full Version : dataChanged, isDirty -- how to tell data was changed...



scott_hollen
29th September 2011, 22:51
Afternoon all --

Done a lot of searching, high and low, and experimenting but I can't seem to hit on a solution to what I'm trying to do...Here's what I have...

QSqlTableModel on a SQlite table with 29 columns...
29 Line edits mapped to these columns (one of them to a combobox)
editStrategy = OnManualSubmit
Request that any change to the data enables a "save" push button, a la SQlite Database Brower (if you've used that)...Basically, the save button doesn't enable until a change to the data has occurred...

So I tried a slot that is fired on a dataChanged signal, but I found that tabbing from line edit to line edit fired it -- is that expected behavior? If not -- I know this can't be that hard -- any suggestions to pull off what I'm trying to do? Basically I want to inform the user that they have changes they need to commit if they try to navigate to another place in the app...

Just when I think I've learned a lot about Qt in the past 9 months (despite my first child's birth, colic and reflux getting in the way), what looks to be obvious and easy implementations humble me...


scott

ChrisW67
30th September 2011, 01:26
The dataChanged() signal should not be emitted until you submitAll() or revertAll() in the manual submit mode (or another view changes the data through the model) so I don't know how exactly you get the behaviour you describe. Are you using a table view or a QDataWidgetMapper? Single view or multiple?

QSqlTableModel::isDirty() can tell you if a given index is dirty or not. If you look for currentChanged() from the view's selection model then check the old index you might be part way there.

scott_hollen
30th September 2011, 02:30
@ChrisW67

I'm doing things very vanilla...Creating a QSqlTableModel to a table with the edit strategy of OnManualSubmit, then the I create a mapper to the lineedits that reflect the data...It's weird -- I didn't expect the slot to be fired just by tabbing from widget to widget...


//***************************
//* Rig Inventory Data... *
//***************************
riginvmodel = new QSqlTableModel(this);
riginvmodel->setTable ("rig_inventory");
riginvmodel->sort (32, Qt::AscendingOrder);
riginvmodel->setEditStrategy (QSqlTableModel::OnManualSubmit);

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

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

ui->EquipIDCB->setModel (riginvmodel);
ui->EquipIDCB->setModelColumn (32);
ui->EquipIDCB->setCurrentIndex (0);

riginvmapper->addMapping (ui->RigInvSerialNumLE, 0);
riginvmapper->addMapping (ui->RigInvNumJointsLE, 1);
riginvmapper->addMapping (ui->RigInvTypeLE, 2);
riginvmapper->addMapping (ui->RigInvWtLE, 3);
riginvmapper->addMapping (ui->RigInvJointLenLE, 4);
riginvmapper->addMapping (ui->RigInvODLE, 5);
.
.
.
riginvmapper->addMapping (ui->EquipIDCB, 32);


riginvmapper->setSubmitPolicy(QDataWidgetMapper::AutoSubmit);
riginvmapper->toFirst ();
.
.
.
connect(riginvmodel, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
this, SLOT(enable_save_button()));



And weirder -- a tabe between line edits results in my SLOT enable_save_button() because called twice!

As for the "isDirty" option -- I was hoping to have a flag I could check based on the model overall, not by index, but I guess if I could get the dataChanged(...) working then I could have it set a flag/enable the "save" button"...

scott_hollen
30th September 2011, 20:37
This is getting really frustrating...Even with no changes to my data, tabbing thru the line edits not only causes the dataChanged() signal to fire, but when that happened I checked the see if the index was dirty, and sure enough it was! And doing a submitALL doesn't change that...


scott

norobro
30th September 2011, 21:04
I don't think you can use the QSqlTableModel::dataChanged() signal with a QDataWidgetMapper and accomplish what you want. From the QDataWidgetMapper docs here (http://doc.qt.nokia.com/4.7/qdatawidgetmapper.html#SubmitPolicy-enum) your choices are AutoSubmit, which triggers the dataChanged signal when you tab through your lineedits or ManualSubmit which won't produce a signal.

Looks to me like you need to connect the signal QLineEdit::textEdited(QString) for each lineedit to a slot that enables your "save" button.

scott_hollen
1st October 2011, 14:40
Thanks for the reply -- I got tired of trying to make this work late last night and that's the exact way I was getting around it...Pain in butt because I have so many fields but you gotta make the client happy, right?

And I do have my mapper set to AutoSubmit but I didn't think to look up the signal that gets fired due to that...

thanks again!


scott

norobro
1st October 2011, 16:48
...Pain in butt because I have so many fields ...Two lines of code should do it if all of your QLineEdits are to be connected:
foreach(QLineEdit *lineEdit, findChildren<QLineEdit *>())
connect(lineEdit,SIGNAL(textEdited(QString)),this, SLOT(enable_save_button()()));
Or, you can subclass QLineEdit, put the connect statement in the ctor and promote the lineEdits you want connected in the designer.

scott_hollen
1st October 2011, 18:31
Whoa, that saves me a LOT of time -- THANKS!!!! I need to be doing this more than as a side project to pick up all that I'm missing as a part-timer...

scot