IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Discussion :

Insertion dans une QListView

  1. #1
    Candidat au Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Juillet 2015
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juillet 2015
    Messages : 6
    Points : 4
    Points
    4
    Par défaut Insertion dans une QListView
    Bonjour, après de nombreux essais je n'arrive pas à identifier la source de mon problème. Je vais essayer d'être le plus clair possible.

    Je veux créer une interface graphique grâce à Qt qui communique avec une BD MySQL.

    J'ai une QListView que j'ai associée à un model qui affiche les pièces/produits associées au projet qui à été préalablement sélectionné (il y'a donc un travail de 'tri' pour l'affichage).

    Lorsque l'utilisateur clique sur le bouton 'ajouter produit' une fenêtre QDialog modale s'ouvre et permet de rentrer un libellé et une référence. Lorsqu'un utilisateur clique sur le bouton valider de cette QDialog je crée une requête qui rentre ces informations dans la base de donnée.

    Voici le code

    MainWindow.cpp

    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
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    MainWindow::MainWindow(int typeUtilisateur, int id_operation, QString projet, QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
     
    ...
     
        // Récupération la liste de pièces associées au projet
            query_2.prepare("SELECT * FROM produit WHERE ref_projet = :id_project");
            query_2.bindValue(":id_project", id_selected_project);
            // On vérifie que des pièces ont été rentrées, si ce n'est pas le cas on envoie un message à l'utilisateur pour l'en informer
            if (query_2.exec() && query_2.first())
            {
                // Réccupère l'index de la colonne du champ ns_interne dans la table produit
                ns_interne_col = query_2.record().indexOf("ns_interne");
                model = new QSqlTableModel(this);
                model->setTable("produit");
                //All changes to the model will be applied immediately to the database.
                model->setEditStrategy(QSqlTableModel::OnFieldChange);
                model->select();
                // On insert dans la liste le model en précisant la colonne
                ui->piecesListView->setModel(model);
                // On enlève les lignes de produit qui ne correspondent pas au projet actuel
                for(int i=0; i < model->rowCount(); i++){
                    index_1 = model->index(i, query_2.record().indexOf("ref_projet"));
                    if(!(model->data(index_1).toInt() == id_selected_project))
                    {
                       ui->piecesListView->setRowHidden(i, true);
                    }
                }
                ui->piecesListView->setModelColumn(ns_interne_col);
            }
            else
            {
                QMessageBox::information(this,"Aucun produit enregistré","Aucune pièce n'a encore été enregistrée pour ce projet \n"
                                                                         "pour rentrer de nouvelles pièces appuyez sur le bouton 'ajouter pièces' situé sous la liste des pièces");
            }
        // Fin de récupération de la liste de pièces associées au projet
     
    }
    // Gestion de l'ajout d'une pièce dans le projet
     
        void MainWindow::on_ajouterPiecesButton_clicked()
     
        {
     
            AjouterProduit* ajoutProd;
     
            ajoutProd = new AjouterProduit(id_selected_project, selectIdOperation, 0);
     
            ajoutProd->setModal(true);
     
            ajoutProd->show();
     
            if (!ajoutProd->exec())
     
            {
     
                qDebug() << "Je rentre dans la boucle";
     
                model->select();
     
                // On enlève les lignes de produit qui ne correspondent pas au projet actuel
     
                for(int i=0; i < model->rowCount(); i++){
     
                    index_1 = model->index(i, query_2.record().indexOf("ref_projet"));
     
                    if(!(model->data(index_1).toInt() == id_selected_project))
     
                    {
     
                       ui->piecesListView->setRowHidden(i, true);
     
                    }
     
                }
     
                ui->piecesListView->setModelColumn(ns_interne_col);
     
            }
     
        }
     
    // Fin de gestion de l'ajout d'une pièce dans le projet

    ajoutdepiece.cpp

    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
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    // Si l'utilisateur clique sur le bouton valider
    void AjouterProduit::on_pushButton_clicked()
    {
       if ((ui->numeroSerieLineEdit->text()).isEmpty())
       {
            QMessageBox::information(this,"Champ vide","Veuillez remplir tous les champs");
       }
       else
       {
           query_1.prepare("SELECT * FROM produit WHERE ref_projet = :ref_projet AND ns_interne = :ns_interne");
           query_1.bindValue(":ref_projet", ref_selected_project);
           query_1.bindValue(":ns_interne", ui->numeroSerieLineEdit->text());
           if (query_1.exec() && query_1.first())
           {
               QMessageBox::information(this,"Produit déjà enregistré","Le numéro de série que vous avez rentré existe déjà dans la base de données");
           }
           else
           {
               query_2.prepare("INSERT INTO produit VALUES(:id_produit, :ns_interne, :ns_client, :version, :ref_projet, 'OK', :ref_oper)");
               query_2.bindValue(":id_produit", NULL);
               query_2.bindValue(":ns_interne", ui->numeroSerieLineEdit->text());
               query_2.bindValue(":ns_client", NULL);
               query_2.bindValue(":version", ref_selected_version);
               query_2.bindValue(":ref_projet", ref_selected_project);
               query_2.bindValue(":ref_oper", ref_selected_oper);
               query_2.exec();
               close();
            }
       }
     
    }
    Mon problème est que cette manière de procéder marche très bien si au moins une pièce se trouve déjà dans la QListView. Mais l'application cesse de fonctionner s'il s'agit de la première pièce.

    Voilà si quelqu'un à une idée d'où vient mon erreur je lui suis reconnaissante d'avance, merci

  2. #2
    Membre émérite
    Avatar de ymoreau
    Homme Profil pro
    Ingénieur étude et développement
    Inscrit en
    Septembre 2005
    Messages
    1 154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur étude et développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 154
    Points : 2 834
    Points
    2 834
    Par défaut
    Quand tu dis que l'application cesse de fonctionner, tu parles d'un crash ou que l'application ne fait juste pas ce qui est attendu (cad mettre à jour la liste) ?
    En cas de crash lance ton appli en debug (Qt Creator permet de faire ça directement avec le mode debug) et trouve à quel endroit le crash se produit dans le code.
    En cas de non fonctionnement, essaye soit en debug soit avec des traces de vérifier étape par étape ce qui fonctionne bien et à quel moment ça ne se passe pas comme il faudrait, est-ce que la requête a l'air bonne, est-ce qu'elle s'exécute correctement (tu ne testes pas le query_2.exec();), est-ce que la base contient bien les données ajoutées ? etc. Si tu ne vois pas à quel moment le problème se produit, passe ces étapes en revue en debug dans le cas où ça fonctionne puis dans le cas où ça ne fonctionne pas, pour comparer et trouver la différence.

    Bonne chance !

  3. #3
    Candidat au Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Juillet 2015
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juillet 2015
    Messages : 6
    Points : 4
    Points
    4
    Par défaut Segmentation fault
    Merci de ta réponse ymoreau

    Alors je l'ai pas bien précisé, il s'agit d'un crash, je reçois un message :
    l'application **** a cessé de fonctionner
    J'ai donc utilisé le mode debugg (c'est très pratique merci pour ça). Au moment du crash il m'envoie le message :
    The inferior stopped because it received a signal from the operating system Signal name : SIGSEGV Signal meaning : Segmentation fault
    et il me précise que l'erreur vient de cette commande :
    dans le MainWindow.cpp
    Sur internet j'ai vu qu'il pouvait s'agir d'une erreur sur un pointeur, mais comme ici cela fonctionne lorsqu'une pièce est déjà rentrée je suis pas sure.. (la liste se met bien à jour dans ce cas et l'application ne plante pas). Ou autre possibilité que j'ai lue : lorsque l'application essaye d'accéder à des données auxquelles il n'a pas accès.

    Du coup j'ai testé ma commande query_2.exec() et effectivement il y'avait bien une erreur (je ne m'étais pas méfiée vu que oui, la base de donnée était bien remplie). Je ne pouvais pas envoyer NULL dans une variable qui ne s'auto incrémentait pas. C'est corrigé alors merci et malheureusement ça n'a pas résolu le problème.

    Alors je sais plus trop où chercher

    Ah oui aussi j'ai regardé la différence qu'il pouvait y avoir lorsque ça plante où pas. J'ai regardé la valeurs des variables à chaque étape et j'ai rien décelé à priori. Donc voilà si tu as une idée de ce que je pourrais regarder encore merci

  4. #4
    Candidat au Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Juillet 2015
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juillet 2015
    Messages : 6
    Points : 4
    Points
    4
    Par défaut Petite précision
    J'ai fais une requête juste avant le et il trouve bien la pièce enregistrée dans la base de données

  5. #5
    Membre émérite
    Avatar de ymoreau
    Homme Profil pro
    Ingénieur étude et développement
    Inscrit en
    Septembre 2005
    Messages
    1 154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur étude et développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 154
    Points : 2 834
    Points
    2 834
    Par défaut
    Effectivement un crash vient presque à tous les coups d'un mauvais pointeur (jamais initialisé ou détruit). Pour ça, une pratique indispensable est d'initialiser à zéro tous les pointeurs sur lesquels tu ne crées pas un objet immédiatement, dans ton cas c'est ta variable model.
    Si tu avais initialisé cette variable à 0, tu aurais sans doute vu qu'en appelant MainWindow::on_ajouterPiecesButton_clicked() ce pointeur serait resté à 0 quand ta base est vide au démarrage. D'après ce que je vois tu crées ton objet model model = new QSqlTableModel(this); uniquement dans le cas où tu as récupéré quelque chose de ta base (à l'intérieur du if), si elle est vide ton objet n'est jamais créé. Plus tard tu vas essayer d'y accéder dans MainWindow::on_ajouterPiecesButton_clicked() et tu appelles select sur un objet qui n'a jamais été créé.

    Je ne pense pas que la création de ton modèle dépende de l'état de ta base, donc tu pourrais envisager de déplacer le code qui initialise le modèle avant ta toute première requête (et en dehors du if donc) dans le constructeur de MainWindow pour être certaine que ton modèle existera toujours. Et ensuite faire les appels à select uniquement quand c'est nécessaire.

  6. #6
    Candidat au Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Juillet 2015
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juillet 2015
    Messages : 6
    Points : 4
    Points
    4
    Par défaut Résolu!
    ça marche, c'est exactement ce que tu as dit! Et je ferais attention la prochaine fois à bien vérifier l'état de mes pointeurs avant de poster.
    Mais merci beaucoup en tout cas, je sais pas combien de temps j'aurais mis avant de enfin trouver ça

  7. #7
    Membre émérite
    Avatar de ymoreau
    Homme Profil pro
    Ingénieur étude et développement
    Inscrit en
    Septembre 2005
    Messages
    1 154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur étude et développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 154
    Points : 2 834
    Points
    2 834
    Par défaut
    C'est normal de faire des erreurs, il faut bien les faire pour apprendre il ne faut pas hésiter à poster.
    L'important c'est d'assimiler les méthodes pour trouver les erreurs tout seul les prochaines fois et gagner du temps, c'est aussi pour qu'on essaye en général d'expliquer le problème et pas juste donner la solution.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [debutant]insertion dans une BDD
    Par EssaiEncore dans le forum ASP
    Réponses: 7
    Dernier message: 10/02/2005, 14h58
  2. INTERBASE 5.5 insertion dans une colonne BLOB
    Par mariustrezor dans le forum Bases de données
    Réponses: 4
    Dernier message: 29/10/2004, 18h06
  3. Extraction d'un .txt et Insertion dans une table
    Par PoPmiSiR dans le forum Access
    Réponses: 8
    Dernier message: 28/10/2004, 19h13
  4. Détection insertion dans une Table
    Par abelman dans le forum MS SQL Server
    Réponses: 5
    Dernier message: 06/07/2004, 14h24
  5. [LG]Tri par insertion dans une liste chainée
    Par mister_dsg dans le forum Langage
    Réponses: 4
    Dernier message: 18/12/2003, 22h34

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo