Results 1 to 5 of 5

Thread: Double QDataWidgetMapper

  1. #1
    Join Date
    Oct 2009
    Posts
    65
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Double QDataWidgetMapper

    Hello to all,
    I've a simple situation that bring me to ask your help for a stupid (I hope) problem.
    I tried to look for the internet but... no way

    This is the case: I'm trying to create a program to fill an administrative document (i.e. an envoice).
    I have an header and some details into two different tables. My problem is on the header; it contain also the CodForn field that is the foreign key of a Fornitori (suppliers) table.

    OK I've create my QDataWidgetMapper and create a QSqlRealtionalTable model to map all my widget to the header table.
    Now, the problem is that I need to map all Fornitori fields so that if my supplier exists the user find it into the table, if it not exist, the user can insert the data by that 3 fields. To got this, i create an other QDataWidgetMapper to map Fornitori table, and using the ManualSubmit I save the data of fornitori before save the header data.

    I thought I could be simple but... the submit() return true but fornitori info not created

    I attach my code, I'm testing it by update an existing element (so using currentIndex of mapper to select data of header table) changing the supplier information. Have you any ideas about where is my mistake??

    Thanks a lot for your time.

    Michelel

    tstrda.ui
    tstrda.cpp
    tstrda.h

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,373
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Thanks
    4
    Thanked 5,019 Times in 4,795 Posts
    Wiki edits
    10

    Default Re: Double QDataWidgetMapper

    I ddn't really understand your problem but I think having 5 data widget mappers does not seem to be a good approach. For complex data situations I usually opt for creating a completely custom model that contains all the data I need and deals with loading and saving of the data according to the data flow model defined for the application.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  3. #3
    Join Date
    Oct 2009
    Posts
    65
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Double QDataWidgetMapper

    Consider two model.
    1) QSqlRelationalTableModel and QDataWidgetMapper to map data of envoice header.
    2) QSqlTableModel to map supplier data.

    I would got this: as you see in .ui file, I've 3 field for supplier's data. When I add a new envoice header, I would like that, compiling those fields, i add into Fornitori tables all data of new supplier and the code created (AUTOINCREMENT ID on table Fornitori) should be used to fill the CodForn (foreign key) field of the envoice header table.

    The same sould be possibile also for the editing; If I edit a header data, I could need to change the supplier data in two way: or changing address or changing completely supplier, so I'd like that, the changes, by submit() of the mapper linked to Fornitori table, are saved into Fornitori table and update the foreign key into header table.

    I attach, a database schema of that two tables.

    db.png

    How could I got it?

    I hope that I explain my need more clearly

    Thanks a lot for your help

    Michele

  4. #4
    Join Date
    Oct 2009
    Posts
    65
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Double QDataWidgetMapper

    This is my code:

    Qt Code:
    1. TstRdA::TstRdA(QString id, int CodUff, QWidget *parent) :
    2. QDialog(parent),
    3. ui(new Ui::TstRdA)
    4. {
    5. ui->setupUi(this);
    6.  
    7. idTest=id;
    8. codUff=CodUff;
    9.  
    10. mdlTestRdA = new QSqlRelationalTableModel(this);
    11. mdlTestRdA->setTable("TestataRdA");
    12. mdlTestRdA->setEditStrategy(QSqlTableModel::OnManualSubmit);
    13. mdlTestRdA->setFilter("CodUfficio=CodUffPC and CodUfficio=CodUffEN and CodUfficio=CodUffVS");
    14.  
    15. connect(ui->cboEnte,SIGNAL(currentIndexChanged(QString)),SLOT(currentEnteChanged(QString)));
    16. connect(ui->cboConto,SIGNAL(currentIndexChanged(QString)),SLOT(currentContoChanged(QString)));
    17. connect(ui->cboSpesa,SIGNAL(currentIndexChanged(QString)),SLOT(currentSpesaChanged(QString)));
    18. connect(ui->txtFRagSoc,SIGNAL(editingFinished()),this,SLOT(getInd()));
    19. connect(ui->cmdSalva,SIGNAL(clicked()),this,SLOT(Salva()));
    20.  
    21. mdlForn = new QSqlTableModel(this);
    22. mdlForn->setEditStrategy(QSqlTableModel::OnManualSubmit);
    23. mdlForn->setTable("Fornitori");
    24.  
    25. mapForn= new QDataWidgetMapper(this);
    26. mapForn->setSubmitPolicy(QDataWidgetMapper::ManualSubmit);
    27. mapForn->setItemDelegate(new QSqlRelationalDelegate(mapForn));
    28. mapForn->setModel(mdlForn);
    29. mapForn->addMapping(ui->txtFRagSoc,mdlForn->fieldIndex("RagSoc"));
    30. mapForn->addMapping(ui->txtFInd,mdlForn->fieldIndex("Indirizzo"));
    31. mapForn->addMapping(ui->txtFCAP,mdlForn->fieldIndex("CapLocProv"));
    32.  
    33. int custIndexF=mdlTestRdA->fieldIndex("CodForn");
    34. mdlTestRdA->setRelation(custIndexF,QSqlRelation("Fornitori","IDForn","IDForn"));
    35.  
    36. mdlForn->select();
    37.  
    38. cforn = new QCompleter(mdlForn,this);
    39. cforn->setCompletionColumn(1);
    40. ui->txtFRagSoc->setCompleter(cforn);
    41.  
    42. int custIndexE=mdlTestRdA->fieldIndex("CodEnte");
    43. mdlTestRdA->setRelation(custIndexE,QSqlRelation("Enti","IDEnte","DescrEnte"));
    44.  
    45. int custIndexVS=mdlTestRdA->fieldIndex("CodVoceSpesa");
    46. mdlTestRdA->setRelation(custIndexVS,QSqlRelation("VociSpesa","IDSpesa","DescrSpesa"));
    47.  
    48. int custIndexCC=mdlTestRdA->fieldIndex("CodCCosto");
    49. mdlTestRdA->setRelation(custIndexCC,QSqlRelation("PianoConti","IDConto","DescrPConti"));
    50.  
    51.  
    52.  
    53.  
    54. mdlEnti = mdlTestRdA->relationModel(custIndexE);
    55. mdlEnti->setFilter(QString("CodUffEN=%1").arg(codUff));
    56. mdlEnti->setEditStrategy(QSqlTableModel::OnManualSubmit);
    57. ui->cboEnte->setModel(mdlEnti);
    58. ui->cboEnte->setModelColumn(mdlEnti->fieldIndex("DescrEnte"));
    59. ui->cboEnte->setItemDelegate(new QSqlRelationalDelegate(this));
    60.  
    61. mdlCConto = mdlTestRdA->relationModel(custIndexCC);
    62. mdlCConto->setFilter(QString("CodUffPC=%1").arg(codUff));
    63. mdlCConto->setEditStrategy(QSqlTableModel::OnManualSubmit);
    64. ui->cboConto->setModel(mdlCConto);
    65. ui->cboConto->setModelColumn(mdlCConto->fieldIndex("DescrPConti"));
    66. ui->cboConto->setItemDelegate(new QSqlRelationalDelegate(this));
    67.  
    68. mdlSpesa = mdlTestRdA->relationModel(custIndexVS);
    69. mdlSpesa->setFilter(QString("CodUffVS=%1").arg(codUff));
    70. mdlSpesa->setEditStrategy(QSqlTableModel::OnManualSubmit);
    71. ui->cboSpesa->setModel(mdlSpesa);
    72. ui->cboSpesa->setModelColumn(mdlSpesa->fieldIndex("DescrSpesa"));
    73. ui->cboSpesa->setItemDelegate(new QSqlRelationalDelegate(this));
    74.  
    75. mapper = new QDataWidgetMapper(this);
    76. mapper->setSubmitPolicy(QDataWidgetMapper::ManualSubmit);
    77. mapper->setModel(mdlTestRdA);
    78. mapper->setItemDelegate(new QSqlRelationalDelegate(this));
    79. mapper->addMapping(ui->txtNRda, mdlTestRdA->fieldIndex("NRdA"));
    80. mapper->addMapping(ui->dtDataRda, mdlTestRdA->fieldIndex("Data"),"date");
    81. mapper->addMapping(ui->chkInv,mdlTestRdA->fieldIndex("chkInvest"));
    82. mapper->addMapping(ui->chkNComm,mdlTestRdA->fieldIndex("chkNComm"));
    83. mapper->addMapping(ui->txtCausInv, mdlTestRdA->fieldIndex("TestoInvest"));
    84. mapper->addMapping(ui->txtNumComm,mdlTestRdA->fieldIndex("NumComm"));
    85. mapper->addMapping(ui->dtDataConsegna, mdlTestRdA->fieldIndex("DataCons"),"date");
    86. mapper->addMapping(ui->dtDataContratto,mdlTestRdA->fieldIndex("DataContratto"),"date");
    87. mapper->addMapping(ui->dtDataPrev,mdlTestRdA->fieldIndex("DataPrev"),"date");
    88. mapper->addMapping(ui->dtDataOScr, mdlTestRdA->fieldIndex("DataOfferta"),"date");
    89. mapper->addMapping(ui->dtDataOVerb, mdlTestRdA->fieldIndex("DataOffVerb"),"date");
    90. mapper->addMapping(ui->txtLuogoCons,mdlTestRdA->fieldIndex("LuogoCons"));
    91. mapper->addMapping(ui->txtResa,mdlTestRdA->fieldIndex("Resa"));
    92. mapper->addMapping(ui->cboEnte,custIndexE);
    93. mapper->addMapping(ui->cboConto,custIndexCC);
    94. mapper->addMapping(ui->cboSpesa,custIndexVS);
    95. mapper->addMapping(ui->spinBox,custIndexF);
    96.  
    97. mdlTestRdA->select();
    98.  
    99.  
    100.  
    101. if (idTest.toInt()==-1){
    102. mdlTestRdA->insertRow(mdlTestRdA->rowCount());
    103. mapper->toLast();
    104. Pulisci();
    105. setWindowTitle(this->windowTitle().replace("########","Nuova"));
    106.  
    107. ui->dtDataRda->setDate(QDate::currentDate());
    108.  
    109. }
    110. else{
    111. Pulisci();
    112.  
    113. setWindowTitle(this->windowTitle().replace("########","Modifica"));
    114.  
    115. for (int i=0; i<mdlTestRdA->rowCount(); i++){
    116.  
    117. QString nrda,codente;
    118. nrda=mdlTestRdA->record(i).field("NRda").value().toString();
    119.  
    120. QSqlQuery getEnte (QString("SELECT IDEnte from Enti where DescrEnte='%1' AND CodUffEN=%2")
    121. .arg(mdlTestRdA->record(i).field("DescrEnte").value().toString())
    122. .arg(codUff));
    123.  
    124. while(getEnte.next())
    125. codente=getEnte.value(0).toString();
    126.  
    127. QString idRec= QString("%1%2").arg(codente).arg(nrda);
    128.  
    129. if (idRec==idTest){
    130. mapper->setCurrentIndex(i);
    131. getInd();
    132. break;
    133. }
    134.  
    135. for (int f=0; f<mdlForn->rowCount();f++){
    136.  
    137. QString rsGen,rsForn;
    138. rsGen = mdlTestRdA->record(i).field("RagSoc").value().toString();
    139. rsForn=mdlForn->record(f).field("RagSoc").value().toString();
    140.  
    141. if(rsGen==rsForn){
    142. mapForn->setCurrentIndex(f);
    143. break;
    144. }
    145.  
    146. }
    147.  
    148.  
    149.  
    150. }
    151.  
    152.  
    153. }
    154.  
    155. connect(ui->cmdSalva, SIGNAL(clicked()),this,SLOT(Salva()));
    156.  
    157.  
    158.  
    159.  
    160. }
    161.  
    162. TstRdA::~TstRdA()
    163. {
    164. delete ui;
    165. }
    166.  
    167. void TstRdA::Salva(){
    168.  
    169. //In this way I update the supplier's data
    170. while(mdlForn->isDirty()){
    171. mapForn->submit();
    172. mdlForn->submitAll();
    173. mdlForn->select();
    174. //mdlTestRdA->relationModel(mdlTestRdA->fieldIndex("CodForn"))->select();
    175.  
    176. }
    177.  
    178. //So I save the envoice's header data
    179. mapper->submit();
    180. mdlTestRdA->submitAll();
    181.  
    182. accept();
    183. }
    184.  
    185. void TstRdA::Pulisci(){
    186.  
    187.  
    188.  
    189. }
    190.  
    191. void TstRdA::currentEnteChanged(QString descr){
    192.  
    193. QSqlQuery getID (QString("SELECT IDEnte from Enti where DescrEnte='%1' and CodUffEN=%2")
    194. .arg(descr)
    195. .arg(codUff));
    196.  
    197. while(getID.next())
    198. ui->txtNumEnte->setText(getID.value(0).toString());
    199.  
    200. }
    201.  
    202. void TstRdA::currentContoChanged(QString descr){
    203.  
    204. QSqlQuery getID (QString("SELECT IDConto from PianoConti where DescrPConti='%1' and CodUffPC=%2")
    205. .arg(descr)
    206. .arg(codUff));
    207.  
    208. while(getID.next())
    209. ui->txtNumConto->setText(getID.value(0).toString());
    210.  
    211.  
    212. }
    213.  
    214. void TstRdA::currentSpesaChanged(QString descr){
    215.  
    216. QSqlQuery getID (QString("SELECT IDSpesa from VociSpesa where DescrSpesa='%1' and CodUffVS=%2")
    217. .arg(descr)
    218. .arg(codUff));
    219.  
    220. while(getID.next())
    221. ui->txtNumSpesa->setText(getID.value(0).toString());
    222.  
    223.  
    224. }
    225.  
    226. void TstRdA::getInd(){
    227.  
    228. QString ragsoc= ui->txtFRagSoc->text();
    229.  
    230. if(mdlForn->isDirty()){
    231.  
    232.  
    233. msg.setWindowIcon(QIcon(":/HGrid/righe.png"));
    234. msg.setText("Le informazioni relative al fornitore non sono state salvate.");
    235. msg.setInformativeText("Salvarle?");
    236. msg.setIcon(QMessageBox::Information);
    237. msg.setWindowTitle("Dati fornitore non salvati");
    238. msg.setStandardButtons(QMessageBox::Yes | QMessageBox::No |QMessageBox::Cancel);
    239. msg.setDefaultButton(QMessageBox::No);
    240.  
    241. int ret = msg.exec();
    242. switch (ret) {
    243. case QMessageBox::Yes:{
    244. mapForn->submit();
    245. mdlForn->submitAll();
    246. break;}
    247. case QMessageBox::No:{
    248. gestForn();
    249. break;
    250. }
    251. }
    252.  
    253.  
    254. }
    255. else{
    256. gestForn();
    257. }
    258.  
    259. }
    260.  
    261. void TstRdA::gestForn(){
    262.  
    263. QString ragsoc=ui->txtFRagSoc->text();
    264.  
    265. mdlForn->setFilter(QString("RagSoc='%1'").arg(ragsoc));
    266. mdlForn->select();
    267.  
    268. if(mdlForn->rowCount()>0){
    269.  
    270. ui->txtFInd->setText(mdlForn->record(0).field(2).value().toString());
    271. ui->txtFCAP->setText(mdlForn->record(0).field(3).value().toString());
    272.  
    273. }
    274. else {
    275. mdlForn->insertRow(0);
    276. mapForn->toFirst();
    277.  
    278.  
    279. ui->txtFRagSoc->setText(ragsoc);
    280. ui->txtFInd->setText("");
    281. ui->txtFCAP->setText("");
    282.  
    283.  
    284.  
    285. }
    286.  
    287. }
    To copy to clipboard, switch view to plain text mode 

    I use txtFRagSoc to get the supplier when I edit a data, and to create It when I create new header data. in this case, If I create a new header data, all data are stored but not the CodForn field (that hold the foreign key of relation).

    Any ideas about it?

    Thanks a lot.

    Michele

  5. #5
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,373
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Thanks
    4
    Thanked 5,019 Times in 4,795 Posts
    Wiki edits
    10

    Default Re: Double QDataWidgetMapper

    Do you insert the new row to the relation table and refresh the model before submitting changes to the main table? Your data will not magically appear in the relation table if you don't manually put it there. Similarily the foreign key will not be mapped in the main table if the relational delegate does not know about it. I really think you should implement a custom model that binds the two datasets into one.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


Similar Threads

  1. QList<double> => QVariant => QList<double>
    By stefan in forum Qt Programming
    Replies: 3
    Last Post: 12th October 2013, 12:17
  2. QDataWidgetmapper
    By locus in forum Qt Programming
    Replies: 7
    Last Post: 5th June 2012, 12:24
  3. Program not finding an existing double in a QList<double>
    By aarelovich in forum Qt Programming
    Replies: 2
    Last Post: 9th May 2011, 21:59
  4. Replies: 2
    Last Post: 24th June 2009, 16:38
  5. QDataWidgetMapper
    By rogerholmes in forum Newbie
    Replies: 4
    Last Post: 24th March 2009, 20:32

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Qt is a trademark of The Qt Company.