Toon posts:

[Qt, C++, Mysql] Rij toevoegen aan QSqlQueryModel subclass

Pagina: 1
Acties:

Onderwerpen


  • Gehakt
  • Registratie: Juli 2002
  • Laatst online: 13-01-2022
Ik snap niet hoe het mechanisme werkt om een rij toe te voegen aan de database door middel van QSqlQueryModel. Ik heb hier een subclass van gemaakt en setData() geimplementeerd. Deze voert op basis van welke column uit de tabel dat hij ontvangt de corresponderende update functie uit voor die column en Id (rij).

Daarnaast heb ik een widget gemaakt en de velden daarvan middels een QDataWidgetMapper klasse gekoppeld aan de corresponderende rijen in de tabel.

Wat ik dus zou kunnen doen is het volgende. Zodra ik het widget open voeg ik een nieuwe (blanco) regel toe aan het eind van de tabel. En ik zet de mapper op deze rij. Zodra dat de velden ingevuld zijn en ik op ok druk zal de mapper voor alle velden setData() in het model aanroepen en deze update de velden netjes in de database.

Echter als een gebruiker de widget opent en vervolgens afsluit door op cancel te drukken zit ik nog steeds met het probleem dat er nu een lege regel in de database staat.

Geen enkele van de voorbeelden op de site tonen aan hoe dit mechanisme werkt of wat de alternatieven zijn dus de informatie op dit gebied en op het internet zijn wat karig.

Het werkt dus wel als je voordat je de waarden zet vanuit je widget eerst een blanco regel aanmaakt en de mapper daar op zet.
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
void InsertWizard::initMapper()
{
   // Sets the model for the standard mapper.
   // m_modelPtr is a smart pointer to the subclassed qsqlquerymodel.
   m_mapperPtr->setModel(m_modelPtr.data());
   
   // Delegate to fill comboxes... default delegate for now.
   m_mapperPtr->setItemDelegate(m_delegatePtr.data());

   // Maps al the fields to the corresponding column (table) in the model. 
   m_mapperPtr->addMapping(ui->reqNameLineEdit,          1);
   m_mapperPtr->addMapping(ui->reqDescription,           2);
   m_mapperPtr->addMapping(ui->reqRenevuePlainTextEdit,  3);
   m_mapperPtr->addMapping(ui->reqRisksPlainTextEdit,    4);
   m_mapperPtr->addMapping(ui->reqTypeComboBox,          5);
   m_mapperPtr->addMapping(ui->reqState,                 6);
   m_mapperPtr->addMapping(ui->reqOwnerName,             7);

   // Sets the submit policy so that it only submits after an explicit call to
   // m_mapperPtr->submit();
   m_mapperPtr->setSubmitPolicy(QDataWidgetMapper::ManualSubmit);

   // Inserts a new (blanc) line in the database and set the mapper on that line.
   m_modelPtr->insertRow(0);
   m_mapperPtr->toLast();
}

Daarnaast snap ik ook het concept van een regel voor een andere regel toevoegen in een database tabel niet. Volgens mij bestaat het concept in een database niet dat je een nieuwe regel toevoegd VOOR een andere regel?

De lege regel wordt door het model door middel van een stored procedure in de database gezet. Aangezien er geen sprake is van een parent of rij voor welke de nieuwe rij ingevoegd moet worden zijn deze beide uitgecomment:
C++:
1
2
3
4
5
6
7
8
bool RequirementModel::insertRow(int /* row */, const QModelIndex & /* aparent */)
{
   qDebug() << "Insert row";
   QSqlQuery query;
   query.prepare("CALL sp_insertEmptyRequirement();");

   return query.exec();
}


Wat informatie van de Qt site.
http://doc.qt.nokia.com/4.7/qsqlquerymodel.html
The model is read-only by default. To make it read-write, you must subclass it and reimplement setData() and flags(). Another option is to use QSqlTableModel, which provides a read-write model based on a single database table.
The sql/querymodel example illustrates how to use QSqlQueryModel to display the result of a query. It also shows how to subclass QSqlQueryModel to customize the contents of the data before showing it to the user, and how to create a read-write model based on QSqlQueryModel.
If the database doesn't return the amount of selected rows in a query, the model will fetch rows incrementally. See fetchMore() for more information.
See also QSqlTableModel, QSqlRelationalTableModel, QSqlQuery, Model/View Programming, and Query Model Example.

[Voor 0% gewijzigd door Gehakt op 16-06-2011 20:51. Reden: Kromme zin aangepast.]


  • yade
  • Registratie: Mei 2002
  • Laatst online: 04-06 23:34
Ik denk dat je moet gaan cachen. Kortom, je slaat alle data tijdelijk op en pas op een bepaald moment persist je het naar de database. Kijk naar hoe ze QSqlTableModel hebben geïmplementeerd.

http://qt.gitorious.org/q...models/qsqltablemodel.cpp

Deze sloten zijn de sleutel tot het probleem:

bool QAbstractItemModel::submit () [virtual slot]
void QAbstractItemModel::revert () [virtual slot]

  • Gehakt
  • Registratie: Juli 2002
  • Laatst online: 13-01-2022
Ik was gister inderdaad ook al voorzichtig tot die conclusie gekomen door naar de implementatie van qsqltablemodel te kijken. In die modellen maken ze intern gebruik van een private model die voor het cachen zorgt.

Een beetje treurig dat dit zo ontzettend slecht beschreven is. Het goed subclassen heeft dus behoorlijk wat meer voeten in de aarde dan ik in eerste instantie verwachte. Als er mensen zijn die andere tips hebben of ervaring hiermee dan ben ik hier nog steeds zeer benieuwd naar.

  • yade
  • Registratie: Mei 2002
  • Laatst online: 04-06 23:34
Ja, het is vrij lastig. Of beter gezegd, veel werk.

De documentatie is inderdaad niet altijd even duidelijk, volledig of expliciet, maar het is een zegen dat de broncode van het framework beschikbaar is.


Tweakers maakt gebruik van cookies

Tweakers plaatst functionele en analytische cookies voor het functioneren van de website en het verbeteren van de website-ervaring. Deze cookies zijn noodzakelijk. Om op Tweakers relevantere advertenties te tonen en om ingesloten content van derden te tonen (bijvoorbeeld video's), vragen we je toestemming. Via ingesloten content kunnen derde partijen diensten leveren en verbeteren, bezoekersstatistieken bijhouden, gepersonaliseerde content tonen, gerichte advertenties tonen en gebruikersprofielen opbouwen. Hiervoor worden apparaatgegevens, IP-adres, geolocatie en surfgedrag vastgelegd.

Meer informatie vind je in ons cookiebeleid.

Sluiten

Toestemming beheren

Hieronder kun je per doeleinde of partij toestemming geven of intrekken. Meer informatie vind je in ons cookiebeleid.

Functioneel en analytisch

Deze cookies zijn noodzakelijk voor het functioneren van de website en het verbeteren van de website-ervaring. Klik op het informatie-icoon voor meer informatie. Meer details

janee

    Relevantere advertenties

    Dit beperkt het aantal keer dat dezelfde advertentie getoond wordt (frequency capping) en maakt het mogelijk om binnen Tweakers contextuele advertenties te tonen op basis van pagina's die je hebt bezocht. Meer details

    Tweakers genereert een willekeurige unieke code als identifier. Deze data wordt niet gedeeld met adverteerders of andere derde partijen en je kunt niet buiten Tweakers gevolgd worden. Indien je bent ingelogd, wordt deze identifier gekoppeld aan je account. Indien je niet bent ingelogd, wordt deze identifier gekoppeld aan je sessie die maximaal 4 maanden actief blijft. Je kunt deze toestemming te allen tijde intrekken.

    Ingesloten content van derden

    Deze cookies kunnen door derde partijen geplaatst worden via ingesloten content. Klik op het informatie-icoon voor meer informatie over de verwerkingsdoeleinden. Meer details

    janee