Bonjour,
Je suis nouveau dans Qt mais je sorts de 20ans de Delphi et bases de données (pas à titre professionnel).
j'ai repris l'exemple "Calendar" fourni avec QT 5.4, que j'ai un peu modifié afin de comprendre les interactions entre Qt, qml, QSqlQueryModel et Listview.
Pour cela, j'ai remplacé le composant Calendar par un Gridview. Sur un click de chaque item du Gridview, j'ajoute un enregistrement à la table Event via:
Dans sqleventmodel.h:
Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
Q_INVOKABLE QList<QObject*> eventsForDate(int numid);
Q_INVOKABLE void AjouteEnr(int numid, const QString mnom);
Dans sqleventmodel.cpp:
Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
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
27
28
29
30
31
32
33
34
void SqlEventModel::AjouteEnr(int numid, const QString mnom)
{
 
    const QString queryStr = QString::fromLatin1("INSERT INTO EVENT values(?,?, '2014-01-01', 36000, '2014-01-01', 39600)");
    //const QString queryStr = QString::fromLatin1("INSERT INTO EVENT values(12,'Salut', '2014-01-01', 36000, '2014-01-01', 39600)");
    QSqlQuery myQuery;
    myQuery.prepare(queryStr);
    myQuery.addBindValue(numid);
    myQuery.addBindValue(mnom);
    myQuery.exec();
} 
 
QList<QObject*> SqlEventModel::eventsForDate(int numid)
{
    this->clear();
    const QString queryStr = QString::fromLatin1("SELECT * FROM Event");
 
 
    QSqlQuery query;
    query.prepare(queryStr);
    //query.addBindValue(numid);
    if (!query.exec())
        qFatal("Query failed");
 
    QList<QObject*> events;
    while (query.next()) {
        Event *event = new Event(this);
        event->setName(query.value("name").toString());
        qDebug() <<  (query.value("name").toString());
        events.append(event);
    }
 
    return events;
}

Dans le main.qml:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
model: eventModel.eventsForDate(calendar.selectedDate)
est remplacé par
Code : Sélectionner tout - Visualiser dans une fenêtre à part
model: eventModel.eventsForDate(row.monnum)
Item de la gridView:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Component {
                 id: appDelegate
 
                 Item {
                     width: 100; height: 100
 
                     Rectangle {
                         id: boutonclavier
                         width: 100; height: 100
                         property int numboutclavier: numfact
 
                         MouseArea {
                             anchors.fill: parent
                             onClicked{
                                 eventModel.AjouteEnr(boutonclavier.numboutclavier, mnom.text)
                                 row.monnum=boutonclavier.numboutclavier
                                  }
                         }

Comme vous pouvez le voir, le modèle simplifié affiche la totalité de la table Event, quelque soit la valeur de numid.
Le problème est le suivant: si je clique sur un item du gridview, un enregistrement est ajouté à la table event, et un nouvel item s'affiche dans la listview.
Par contre, si je clique plusieurs fois sur le même item, la table est modifiée mais pas la listview. Il faut cliquer un autre item du GridView pour mettre à jour la liste.

Ma conclusion est la suivante: la liste n'est mise à jour que si numid est modifié (alors qu'il n'influe pas le résultat de la requête). Pourtant dans la fenêtre "sortie de l'application" de Qt, la fonction qDebug() << (query.value("name").toString()); renvoie bien l'ensemble des enregistrements après ajout d'un nouveau, donc le modèle est bien mis à jour?
Suites à de nombreuses recherches, je pense qu'il manque une mise à jour du nombre d'enregistrements à afficher dans la listview, avec un rowcount() peut-être, mais là je ne trouve pas la solution.

Si quelqu'un avait une solution. Merci d'avance.