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 :

Mise en place de MVC donnant une SegFault

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 28
    Points : 8
    Points
    8
    Par défaut Mise en place de MVC donnant une SegFault
    Bonjour,

    Voila je tente de faire mon 1er programme sous Qt et j'ai voulu utiliser le système MVC de Qt avec un QStandardItemModel et QListView. Le modèle et la vue sont dans 2 classes différentes (j'ai déclaré le QStandardItemModel en public pour faciliter l'accès).

    je n'ai pas d'erreur de compilation mais quand je debug, j'ai un segfault sur la méthode setModel(). Pour préciser, j'utilise des pointeurs.

    Y-a-t-il quelque chose en plus a déclarer dans la classe de la vue, un ordre a respecter dans sa construction (liaison vue/modèle a faire avant d'ajouter la vue dans une fenêtre)?

  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
    La doc sur le sujet est un peu longue, mais je pense qu'il n'est pas inutile de s'en imprégner car ce n'est pas une partie très facile je trouve. Pour commencer tu as un exemple minimal de model/view :
    Model/View Programming

    Pour ton problème il faudrait un minimum de code pour t'aider, tu dis utiliser une QListView, dans ce cas tu devrais plutôt utiliser QAbstractListModel. Car QAbstractItemModel est la classe la plus générique des modèles capable de gérer une arborescence plus complexe qu'une liste. QAbstractListModel est plus simple à utiliser.

    Est-ce que tu es sûr que le segfault vient de setModel ? Il est plus probable que c'est lorsque la vue va appeler les fonctions du modèle (principalement data, et rowCount) que tu auras des problèmes, car c'est à ce niveau que tu dois toi même gérer l'accès aux données.

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 28
    Points : 8
    Points
    8
    Par défaut
    Pour ce qui est de l'utilisation de QStandardItemModel avec QListView, je sais que sa ne parait pas logique mais c'est ce qui me semble le mieux concorder puisque je ne souhaite afficher que le 1er élément dans l'arborescence de chaque enregistrement.

    Un peu de code :
    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
    //vue.h
    ...
    private:
        QListView *vue1, *vue2;
    ...
     
    //vue.cpp
    vue::vue()
    {
    ...
        vue1 = new QListView;
        vue2 = new QListView;
     
        vue1->setModel(PtrClassModel->PtrModel);
        vue2->setModel(PtrClassModel->PtrModel);
    }
     
    //ClassModel.h
    ...
    public :
        QStandardItemModel *model;
    ...
    Je n'ai pas mis le code du remplissage du modèle mais j'utilise le même pointeur sur un QStandardItem pour chaque enregistrement.
    Est-ce problématique?

    Sinon je ne suis pas sûr que le problème vienne de setModel() mais toujours est-il que quand je lance le débugger il bloque sur cette ligne.

  4. #4
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Points : 15 620
    Points
    15 620
    Par défaut
    Car QAbstractItemModel est la classe la plus générique des modèles capable de gérer une arborescence plus complexe qu'une liste.
    En fait, la classe la plus "générique" est QAbstractItemModel. QStandardItemModel est un modèle "clé en main" permettant d'utiliser directement n'importe quelle structure de données derrière.

    Normalement, tu as une structure de données et tu crées un modèle permettant d'y accéder (dérivant de QAbstractXXXModel : un QAbstractListModel si ta structure de données est une liste, QAbstractTableModel si ta structure est une table, QAbstractItemModel dans la cas général, etc.), en ré-implémentant les fonctions d'accès aux données : data, setData, etc.

    QStandardItemModel permet d'utiliser directement un modèle sans avoir à redéfinir les fonctions data, setData, etc. et sans avoir besoin de créer une structure de données derrière. La conséquence de cette généricté est le coût en terme de performance.

    Tu peux donc utiliser QStandardItemModel sans problème. Et avec n'importe quelle vue.

    Je n'ai pas mis le code du remplissage du modèle mais j'utilise le même pointeur sur un QStandardItem pour chaque enregistrement.
    Est-ce problématique?
    Regarde les exemples de code dans QStandardItemModel : il faut créer un nouvel QStandardItem pour chaque nouvel élément inséré dans le modèle.

    Sans information détaillée, je pense que le problème vient de là.

  5. #5
    Futur Membre du Club
    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 28
    Points : 8
    Points
    8
    Par défaut
    Il y a effectivement un problème avec le modèle.
    Je déclare maintenant un nouveau pointeur QStandardItem pour chaque enregistrement et maintenant sa me donne plus de précision puisque je bloque dans QAbstractItemView.cpp sur cette ligne dans setModel() :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    // These asserts do basic sanity checking of the model
        Q_ASSERT_X(d->model->index(0,0) == d->model->index(0,0),
                   "QAbstractItemView::setModel",
                   "A model should return the exact same index "
                   "(including its internal id/pointer) when asked for it twice in a row.");
    Si j'ai bien compris, sa vérifie la validité du modèle.

    histoire de donner plus d'info, mon modèle gère un parc informatique (rempli grâce à un fichier .csv) et chaque enregistrement correspond a une association nom d'hôte / adresse mac (d'où le QListView puisque je n'affiche que le nom) dont voici le code :

    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
    //Parc.h
    #ifndef PARC_H
    #define PARC_H
    #include <string>
    #include <fstream>
    #include <iostream>
    #include <sstream>
    #include "gui.h"
    #include <QStandardItemModel>
    #include <QStandardItem>
     
    class Parc
    {
     
        public :
            Parc();
            void setInterface(Gui &maGui);
            QStandardItemModel *ParcInfo;
     
        private :
            Gui *PtrGui;
    };
    #endif // PARC_H
    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
    //Parc.cpp
    #include "parc.h"
     
    Parc::Parc()
    {
     
        ParcInfo = new QStandardItemModel();
     
        // le constructeur de ifstream permet d'ouvrir un fichier en lecture
        std::ifstream fichierListeParc("listeParc.csv");
        if ( fichierListeParc )
        {
            std::string ligne;
            std::stringstream iss;
            std::string mot;
            std::string nom;
            std::string mac;
            bool passed = false;
     
            while (std::getline( fichierListeParc, ligne))
            {            
                QStandardItem *itemNom = new QStandardItem();
                QStandardItem *itemMac = new QStandardItem();
                iss.str(ligne);
                while(std::getline(iss, mot, ','))
                {
                    if(!passed)
                        nom = mot.c_str();
                    else
                        mac = mot;
                    passed = true;
                }
                itemNom->setText(QString::fromStdString(nom));
                itemMac->setText(QString::fromStdString(mac));
                ParcInfo->appendRow(itemNom);
                itemNom->appendRow(itemMac);
                iss.clear();
                passed = false;
            }
            fichierListeParc.close();
        }
        else
        {
            PtrGui->AffMsg1("erreur a l'ouverture du fichier");
        }
    }
     
    void Parc::setInterface(Gui &maGui)
    {
        PtrGui = &maGui;
    }
    edit : les items récupèrent les bonnes valeurs mais n'ont pas l'air de s'ajouter au modèle quand j'appel ParcInfo->appendRow().

  6. #6
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Points : 15 620
    Points
    15 620
    Par défaut
    Bonjour

    Un peu de lecture

    J'ai testé ton code, il fonctionne correctement...

    Tu crées bien d'abord ton modèle puis la vue ? (puisque tu donnes le modèle à la vue dans le constructeur de la vue)

    Plusieurs remarques :

    - Pas besoin d'utiliser un pointeur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    QStandardItemModel *ParcInfo;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    QStandardItemModel ParcInfo;
    - Qt fournit des outils de manipulation de fichier plus "mieux" que les streams standard. A utiliser (en complément avec QTextStream et QString) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::ifstream fichierListeParc("listeParc.csv");
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    QFile file("listeParc.csv");
    - Si ton modèle ne contient qu'une liste de chaine de caractères, tu peux utiliser directement QStringListModel, qui est un modèle utilisant une liste comme structure de données.

    Et dans ce cas, tu n'as pas besoin de lire l'adresse MAC.

    - Si au contraire, tu souhaites quand même conserver l'adresse MAC dans le modèle (pour un usage éventuel ultérieur, ce qui évitera de lire 2 fois le fichier si tu en as besoin), je pense qu'il vaut mieux stocker les données sous forme de table dans le modèle plutôt que sous forme d'arbre.

    Actuellement, avec la ligne suivante, tu stockes l'adresse MAC comme enfant du nom, d'où une structure en arbre (tu peux le vérifier en utiliser un QTreeView à la place d'un QListView, ça fonctionne sans problème).

    Pour stocker les données sous forme de table, tu dois ajouter les éléments avec setItem(row, col, item). Par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ParcInfo.setItem(row, 0, new QStandardItem(QString::fromStdString(nom)));
    ParcInfo.setItem(row, 1, new QStandardItem(QString::fromStdString(mac)));
    ++row;
    Pour l'affichage, ça ne change rien : utiliser une QListView affichera la première colonne de la table.

    - Tu donnes un pointeur vers ta classe GUI = couplage fort entre tes classes = maintenance plus complexe, que tu pourrais éviter en utilisant les signaux/slots.

    - Tu utilises le pointeur vers ta classe GUI pour afficher une erreur de lecture du fichier dans le constructeur, alors que tu fournis ce pointeur à ta classe modèle dans une autre fonction. En cas d'erreur de lecture du fichier, tu essaies donc d'utiliser un pointeur invalide = erreur !

    Le code final pourrait ressembler à :
    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
    #ifndef MA_VUE_H
    #define MA_VUE_H
     
    #include <QtGui/QListView>
    #include <QStandardItemModel>
    #include <QtCore/QFile>
    #include <QtCore/QTextStream>
    #include <QtCore/QStringList>
     
    class MaVue : public QListView
    {
        Q_OBJECT
     
    public:
        MaVue(QWidget *parent = 0) : QListView(parent)
        {
            QFile file(":/ListeParc.csv");
     
            if (file.open(QIODevice::ReadOnly | QIODevice::Text))
            {
                QTextStream in(&file);
                QString line = in.readLine();
     
                int row = 0;
     
                while (!line.isNull())
                {
                    QStringList list = line.split(',');
                    for (int col=0; col<list.size(); ++col)
                        model.setItem(row, col, new QStandardItem(list[col]));
                    ++row;
     
                    line = in.readLine();
                }
                // file.close(); inutile, appelé par destructeur de QFile
     
                setModel(&model);
            }
        }
     
    private:
        QStandardItemModel model;
    };
     
    #endif // MA_VUE_H

  7. #7
    Futur Membre du Club
    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 28
    Points : 8
    Points
    8
    Par défaut
    Citation Envoyé par gbdivers Voir le message
    - Si ton modèle ne contient qu'une liste de chaine de caractères, tu peux utiliser directement QStringListModel, qui est un modèle utilisant une liste comme structure de données.

    Et dans ce cas, tu n'as pas besoin de lire l'adresse MAC.

    - Si au contraire, tu souhaites quand même conserver l'adresse MAC dans le modèle (pour un usage éventuel ultérieur, ce qui évitera de lire 2 fois le fichier si tu en as besoin), je pense qu'il vaut mieux stocker les données sous forme de table dans le modèle plutôt que sous forme d'arbre.

    Actuellement, avec la ligne suivante, tu stockes l'adresse MAC comme enfant du nom, d'où une structure en arbre (tu peux le vérifier en utiliser un QTreeView à la place d'un QListView, ça fonctionne sans problème).
    En fait c'est un programme de Wake On Lan donc je réutilise l'adresse mac dans la construction du paquet magique.

    Citation Envoyé par gbdivers Voir le message
    - Tu donnes un pointeur vers ta classe GUI = couplage fort entre tes classes = maintenance plus complexe, que tu pourrais éviter en utilisant les signaux/slots.
    J'ai effectivement déjà tenté d'utiliser le système signaux/slots en faisant le connect() dans le main mais rien ne répondait j'ai donc abandonné pour utiliser les pointeurs.

    Citation Envoyé par gbdivers Voir le message
    - Tu utilises le pointeur vers ta classe GUI pour afficher une erreur de lecture du fichier dans le constructeur, alors que tu fournis ce pointeur à ta classe modèle dans une autre fonction. En cas d'erreur de lecture du fichier, tu essaies donc d'utiliser un pointeur invalide = erreur !
    c'est vrai qu'en y réfléchissant c'est bizarre mais le pire c'est que sa fonctionne !

    Donc histoire de faire quelque chose de propre je vais retenter d'utiliser les signaux/slots et je reviendrais sans doute ici quand je retrouverais mes problèmes.

  8. #8
    Futur Membre du Club
    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 28
    Points : 8
    Points
    8
    Par défaut
    voila on y est

    donc j'ai mis en commentaire tout ce qui se rapportait aux pointeurs sur mes 2 classes remis en place le système de signaux / slots (juste sur l'affichage du message pour tester).

    le signal est émis dans la classe parc (elle hérite donc maintenant de QObject pour la macro dans la définition de la classe).
    pour le slot, j'ai tout simplement déplacé la déclaration de public vers public slots et je connect() le tout dans le main.

    et bien entendu rien ne se passe alors que je passe forcément dans la boucle ou est émis le message.

    en debug pas à pas sa va même jusqu'à planter

    voici le code du main :
    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
    #include <QApplication>
    #include "gui.h"
    #include "parc.h"
     
    int main(int argc, char *argv[])
    {
        QApplication app(argc, argv);
     
        Gui interface;
        Parc mParc;
     
        QObject::connect(&mParc, SIGNAL(msg(QString)), &interface, SLOT(AffMsg1(QString)));
     
        interface.show();
     
        return app.exec();
    }

  9. #9
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Points : 15 620
    Points
    15 620
    Par défaut
    A quel moment le signal est émis ? Parce que si c'est dans le constructeur de Gui ou de Parc, c'est normal que rien ne se passe puisse que tu fais le connect après la création de tes objets.

  10. #10
    Futur Membre du Club
    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 28
    Points : 8
    Points
    8
    Par défaut
    Effectivement mais sa complique largement les choses si je doit donner au connect() un pointeur sur les objets.

    j'ai l'impression d'être dans une impasse car ce message doit être émis dans le constructeur.

  11. #11
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Points : 15 620
    Points
    15 620
    Par défaut
    Ce n'est pas forcement plus compliqué. C'est une question de conception.

    Actuellement, en mettant la lecture du fichier dans le constructeur, tu implémentes ta classe de façon à ce que 1 objet ParcInfo = 1 structure de parc.
    Il est pertinent de se dire que l'on pourrait souhaiter que le parc puisse être modifié et que l'on ne souhaite pas devoir créer un nouvel objet ParcInfo. La solution est alors simplement de transférer le code contenu dans le constructeur dans une fonction update() (par exemple).
    Le code deviendrait alors :
    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
    class ParcInfo : public QObject
    {
       Q_OBJECT
    signals:
       void msg(...);
    public:
       void update();
       void setFilename(const QString& filename); // pour pouvoir changer le fichier à lire ;)
    };
     
    int main(...)
    {
       // étape 1 : on créer les objets que l'on utilise dans le programme
       QApplication app(argc, argv);
       Gui interface;
       ParcInfo mParc;
     
       // étape 2 : on connecte les objets entre eux
       QObject::connect(&mParc, SIGNAL(msg(QString)), &interface, SLOT(AffMsg1(QString)));
     
       // on initialise nos objets
       mParc.update();
       interface.show();
     
       return app.exec();
    }
    Bon courage

  12. #12
    Futur Membre du Club
    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 28
    Points : 8
    Points
    8
    Par défaut
    Ok merci on avance je vais finir par y arriver.(il était quand même grand temps que je me remette à programmer avant d'avoir tout oublié )

    Le signal fonctionne maintenant correctement reste a trouver pourquoi QFile n'ouvre pas le fichier

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    QFile fichierListeParc("listeParc.csv");
     
    if (!fichierListeParc.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        ...
    }
    else
    {
        emit msg("erreur a l'ouverture du fichier");
    }
    listeParc.csv est présent a la racine du projet et dans debug (je code sous Qt creator) et le signal est émis que je lance direct le .exe dans debug ou via l'ide

    Je met quand même résolu pour le segfault.

  13. #13
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Points : 15 620
    Points
    15 620
    Par défaut
    Probablement un problème de répertoire.

    Qt Creator compile par défaut en "shadow build" : les fichiers de compilation (.o, moc_xxx.cpp) et les fichiers binaires ne sont pas dans le répertoire des sources mais dans le répertoire "build_bidule_destop" (ou quelque chose comme ça). Comme tu utilises la syntaxe "listeParc.csv", l'exécutable recherche le fichier dans le répertoire courant, ie le répertoire de build.

    Plusieurs solutions :
    - tu désactives le shadow build
    - tu copies le fichier dans le répertoire de build
    - tu mets le fichier dans un fichier de ressources .qrc
    - tu ajoutes un dialogue pour sélectionner le fichier à lire
    - probablement plein d'autres trucs

  14. #14
    Futur Membre du Club
    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 28
    Points : 8
    Points
    8
    Par défaut
    Pour le shadow build j'avais pas compris l'utilité donc il était déjà désactivé.
    sinon que je passe par une boite de dialogue ou pas, la méthode reste la même c'est juste la façon de récupérer le chemin qui change donc je ne pense pas que sa va changer grand chose.

    J'ai tenté de faire la déclaration sans nom de fichier dans le .h et d'utiliser setFileName() dans le .cpp mais le résultat est le même.
    Dans les 2 cas, quand je passe au debug, le QFile ne contient aucune valeur.

    Bien entendu je suis certain de la présence du fichier et de son nom.

    edit : Bon je vais me faire tout petit pour ce problème mais c'est juste un test mal fait dans le if

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

Discussions similaires

  1. Mise en place de flux dans une page
    Par Publicnew dans le forum ASP.NET
    Réponses: 4
    Dernier message: 07/03/2015, 12h36
  2. Réponses: 2
    Dernier message: 07/06/2012, 20h05
  3. [SSL / MVC ] Mise en place d'un SSL sur une architecture MVC
    Par Kaldyris dans le forum Sécurité
    Réponses: 3
    Dernier message: 06/12/2010, 07h47
  4. Utilisation du pattern Observateur dans la mise en place d'une architecture MVC
    Par Guyiom dans le forum Langages de programmation
    Réponses: 2
    Dernier message: 25/09/2009, 17h14
  5. [VB.NET] Mise en place d'une progress bar
    Par Hoegaarden dans le forum Windows Forms
    Réponses: 14
    Dernier message: 19/10/2004, 09h23

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