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 :

Modèle-vue-délégué

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre régulier
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Octobre 2014
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2014
    Messages : 7
    Par défaut Modèle-vue-délégué
    Bonjour à tous,

    Je suis entrain de développer enfin d'essayer, une application de gestion de devis et de factures.
    J'ai bien avancé, mais là je bloque sur l'architecture Model / view delegate....

    Je m'explique, lorsque je lance mon application la vue est chargée uniquement avec les entêtes: libellé, prix ht etc... (c'est ce que je souhaite), ensuite je recherche les articles à ajouter à mon devis depuis une boite de dialogue qui enrichis mon model en fonction de mes demandes (cela fonctionne), par contre la vue ne ce met pas à jour et je bloque, je n'arrive pas à trouvé une fonction me permettant de le faire !!!
    Si quelqu'un à une idée je suis preneur.

    Par avance merci.

  2. #2
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,

    Avec un peu de code, nous aurions, sans aucun doute, beaucoup plus facile à t'aider

    Tu n'est pas obligé de nous fournir le code de tout le projet, mais le code de la fonction qui met ton modèle à jour serait surement intéressant, car il nous donnerait une bonne idée de ce qu'il te manque

    Ceci étant dit, je présumes que tu ajoutes des éléments avec les fonction insertRow(s) / insertColumn(s) de ton modele.

    L'idee, c'est que, avant de faire appel à cette fonction, tu appelle la fonction beginInsertXXX (remplace le XXX par Rows / Columns selon ta situation particulière) et que, une fois que tu as ajouté l'ensemble des éléments qui t'intéressent, tu fasse appel à la fonction endInsertXXX équivalente.

    Ces deux fonctions vont obliger le modèle à émettre des signaux (auxquels ta vue est normalement déjà connectée) indiquant le début et la fin de la mise à jour de ton modèle :
    • le signal de début de la mise à jour du modèle va sans doute empêcher la modification des valeurs des éléments visibles (et modifibles, s'il y en a, bien sur)
    • le signal de fin de la mise à jour va réactiver la modification des valeurs des éléments visibles (et modifiables, s'il y en a, bien sur) et forcer la vue à se mettre à jour
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  3. #3
    Membre régulier
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Octobre 2014
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2014
    Messages : 7
    Par défaut
    Bonsoir Kohala01,

    Tout d'abord merci pour ton attention.

    Effectivement, j'aurais pu mettre un exemple, mais je souhaitais que la discussion soit engagée afin de mettre les morceaux de code demandé pour éviter de polluer l’énoncé du PB. Voici la fonction qui met mon model à jour:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    void CreateDevis::ajouterMateriel(QString strNomArticle)
    {
       std::cout <<"AjouterMateriel : " << strNomArticle.toStdString() << std::endl;
       model->requette(strNomArticle);//Fonction qui recupere les infos de l'article dans une BDD (prix, ref etc...)
       std::cout <<"Nombre de ligne du model: " << model->rowCount() << std::endl;
       //Le model est bien mis à jour, mais pas la vue,
       //et là je ne sais pas pourquoi....
    }
    Et voici la fonction membre requette() de mon model, chargée de récupérer les informations de la BDD:
    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
     
    void ModelDevis::requette(QString str )
    {
        lineItem *item = new lineItem;
     
        //Récupération des données souhaitées:
        //Utilisation de bindValue et boundValue de Qt:
        query.prepare("SELECT nom_article, ref_four,"
                      "prix_achat_ht, prix_vente_ht"
                      " FROM materiel.electrique WHERE nom_article = :nom ");
        query.bindValue(":nom", str.toUpper());//Permet de ce positionner à la bonne ligne:
        query.exec();
     
     
        while(query.next())
        {
            item->setRef(query.value(1).toString());
            item->setLabel(query.value(0).toString());
            //lineitem->setQuantite(query.value(x).toString());
            item->setPrixAchat(query.value(2).toString());
            item->setPrixVente(query.value(3).toString());
     
            lineitem.append(item);
         }
    }
    Enfin voici la methode virtuelle data() redéfinis pour mon model personnalisé:
    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
     
    QVariant ModelDevis::data(const QModelIndex &index, int role) const
    {
        int row = index.row();
        int col = index.column();
    if(role == Qt::DisplayRole)
      {
        if (col == 0)
            return lineitem[row]->getLabel();
        if (col == 1)
            return lineitem[row]->getRef();
        if (col == 2)
            return lineitem[row]->getPrixAchat();
        if (col == 3)
            return lineitem[row]->getPrixVente();
        if (col == 4)
            return lineitem[row]->getLabel();
     
      for(auto x = 0; x<rowCount();x++){
            for(auto y = 0; y<columnCount();y++){
                return Qt::AlignRight + Qt::AlignVCenter;
            }
        }
     }
        //emit dataChanged(index, index);
          return QVariant();
    }
    Mon model se met bien à jour, mais pas la vue, par contre il est vrai que je n'utilise pas les fonctions insertRow(s) / insertColumn(s) ni même
    beginInsertXXX, j'avoue avoir un peu de mal à comprendre les subtilités des Model/view deleguate....
    Quand pensez vous ?

  4. #4
    Membre régulier
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Octobre 2014
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2014
    Messages : 7
    Par défaut
    Du coup je viens de relire la documentation Qt (je galère un peu avec l'anglais ), mais grâce a vos informations je me suis concentré
    sur les fonctions insertRow(int row, const QModelIndex &parent = QModelIndex()) et beginInsertRows(const QModelIndex &parent, int first, int last).
    Ensuite j'ai implémenté la fonction insertRowinsertRow(int row, const QModelIndex &parent = QModelIndex()), puis je l'ai surchargée afin
    d’appeler la méthode requette(QString) directement et tout fonctionne comme je le souhaite.

    Merci beaucoup pour votre aide.

    Voici la fonction concernée:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    bool ModelDevis::insertRow(int row, const QModelIndex &index, QString data)
    {
        this->beginInsertRows(index,this->rowCount(),this->rowCount());
        requette(data);
        this->endInsertRows();
        nbrLigne += 1;
        return true;
    }

  5. #5
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Citation Envoyé par Tnerual42 Voir le message
    Merci beaucoup pour votre aide.
    Ce fut un plaisir

    Mais je suis très mal à l'aise par rapport à ton code, car, selon moi, ta requête SQL n'a rien à faire dans l'histoire. Je m'explique.

    Quand tu décide d'ajouter une ligne à ton devis (typiquement, lorsque tu en vient à appeler la fonction ajouterMateriel ), tu ne va -- normalement -- pas laisser l'utilisateur de ton application essayer d'ajouter un matériel "tiré du néant" à ton devis:

    L'un dans l'autre, tu vas lui présenter (sans doute dans un formulaire séparé) une liste des matériaux présents dans la base de données, parmi laquelle il pourra en choisir un qui sera ajouté au devis.

    Ta requête SQL devrait donc, dans l'idéal, prendre place... au niveau de ce formulaire séparé, et tu devrais donc récupérer de ce formulaire l'ensemble des informations (une QStringList me semble pas mal pour l'occasion) correspondant au matériau sélectionné, et qui serait transmise à ta fonction ajouterMatériel.

    Je vais réfléchir pour te donner une idée précise de ce que je ferais si j'étais toi, mais, une chose est sure : quand on en arrive au point de provoquer l'ajout d'un élément à ton devis, il n'est clairement plus temps de faire une requete SQL pour savoir ce qu'il faut y ajouter
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  6. #6
    Membre régulier
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Octobre 2014
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2014
    Messages : 7
    Par défaut
    Citation Envoyé par koala01 Voir le message

    Mais je suis très mal à l'aise par rapport à ton code, car, selon moi, ta requête SQL n'a rien à faire dans l'histoire. Je m'explique.
    Il est vrai que je me suis posé la question concernant l’intégration des requêtes SQL au sein de mon code au début de mon projet. Car effectivement j'ai plusieurs fenêtres graphiques qui communiquent avec la base de données pour afficher des informations, afin de m'aider à choisir. Pour ce cas voici la logique que j'ai choisi: Depuis la fenêtre principale, j'ai un menu devis-facture dans laquelle j’accède à l'action de créer un nouveau devis ce qui génère:

    - Appel de la class créatDevis() qui contient l'interface graphique dont la vue tableView() des articles et de la main d’œuvre du devis.
    - Depuis cette interface j’accède via un bouton connecté au slot rechercheMateriel() à une nouvelle boite de dialogue.
    - Ce dlg me permet d'affiner mon choix, elle affiche notamment un QComboBox me proposant du matériel (uniquement leur nom) en fonction de cases à cocher (afin de limiter ces propositions).
    - Lorsque je valide mon choix en cliquant sur un bouton ajouter j'appelle un nouveau slot dont la connexion se fait depuis la fonction rechercheMateriel(), ainsi je récupère le Qstring (nom de l'article) qui me permet de faire une requête SQL ciblée pour récupérer les informations nécessaires au devis (prix ht, ref etc...) c'est à ce moment la qu’intervient la mise à jour de mon model et ensuite de la vue.

    Il est vrai que je pourrai utiliser la requette SQL en amont et plutôt que de communiquer un Qstring communiquer directement une QlistItem, si selon vous c'est une meilleure pratique je le ferai car le but principal de ce développement est d’apprendre les bonnes pratiques des le départ.
    Qu'en pensez vous? si besoin je peux vous communiquer des extraits de code.

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

Discussions similaires

  1. Modéle Vue Contrôleur (MVC)
    Par mine87 dans le forum ALM
    Réponses: 2
    Dernier message: 08/01/2010, 17h00
  2. Modèle/vue , modèle personnalisé
    Par Kymic dans le forum Qt
    Réponses: 4
    Dernier message: 01/08/2009, 17h15
  3. [MVC] Communication Modèle, Vue
    Par dahtah dans le forum MVC
    Réponses: 4
    Dernier message: 25/10/2007, 17h25
  4. Champ de texte et MVC (modèle vue contrôleur)
    Par three minute hero dans le forum Windows
    Réponses: 1
    Dernier message: 22/02/2007, 11h04
  5. [JSP][Servlet][Javabean] Modèle Vue Controleur
    Par ay_pepito dans le forum Servlets/JSP
    Réponses: 4
    Dernier message: 04/02/2004, 10h05

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