wxDev.fr, le portail francophone consacré à wxWidgets ! ( The french portal for wxWidgets )  
Esp. membre
Recheche rapide



Recherche avancée
Statistiques
Membres inscrits :599

Membres en ligne : 0
Invités en ligne : 9
Pub hébergeur
Pourquoi cette pub ?

Valid XHTML 1.0 Transitional

Valid CSS2

Menu forum (navigation):
Pages: 1  
 
Accueil » Accueil forums » Utilisation générale wxWidgets
» wxWidget et base de données, affilier un id à un élément d'un contrôle
Conversation (Résolue) : wxWidget et base de données, affilier un id à un élément d'un contrôle
13-04-2010 10:31:02  wxWidget et base de données, affilier un id à un élément d'un contrôle #1
freem (Nouveau membre)
Inscrit le : 09-04-2010
Messages: 8
Snippets: 0
Tutoriels: 0
Hors ligne
Bonjour

Je n'utilise les wxWidget que depuis peu, et j'ai jusqu'à maintenant réussi à me débrouiller avec la doc et diverses info collectées sur le net.

Seulement, là, je ne vois vraiment pas comment résoudre ce problème. Je ne suis même pas sûr d'avoir bien identifié sa source, pour être franc.

Bon.
En gros, j'ai une base de données (firebird en l'occurrence, que j'attaque avec la librairie IBPP). Mon programme est censé en être l'interface sur le poste client.
J'utilise des tables pour permettre des menus déroulants qu'il sera possible de remplir avec une simple requête insert. Ces tables ont donc un ID et un label, en général (éventuellement d'autres infos, mais ce n'est pas encore le cas et ne sera pas source de problème au final).
Une (des) autre table contient des références à ces tables (foreign key, un peu l'équivalent des pointeurs).
Mon problème, c'est que les listes déroulantes et autres combobox ne contiennent que des labels, dont on peut récupérer la position dans la liste.
Pour une question d'accès des utilisateurs, j'ajoute dans certaines de manière logicielle une entrée "ajouter" (plus simple que d'aller chercher un bouton planqué à 3 km de la boîte de dialogue) et pour toutes, une entrée correspondant à la frappe actuelle de l'utilisateur (pour permettre de n'afficher que les labels commençant par ce que l'utilisateur à entré, ça vaut mieux quand il y à trop d'enregistrements, par exemple dans la liste des communes de France ou d'un département ^^)
J'aurais aimé associer l'id correspondant au label dans la BDD ou mettre une valeur spécifique dans le cas des 2 entrées ajoutées par le logiciel, donc, j'ai tenté les wxClientData, mais je ne comprend pas comment ça marche, ce qui engendrais des crash et une incohérence des données sur les derniers éléments du contrôle (j'ai cherché des infos dessus, mais je n'ai rien trouvé qui me permette de comprendre leur fonctionnement).
J'ai donc pensé à utiliser un std::vector<long*> (déclaré public bien sûr) pour chacune de ces listes, qui appartiens à la classe possédant le contrôle. (un pointeur, parce que ça me permet de mettre des null quand l'élément à été ajouté par le logiciel)
Et, la encore, j'ai un souci.
La méthode qui permet de remplir ces listes (ainsi que l'objet qui me permet d'utiliser la bdd) à été déclarée dans la classe principale de l'application (celle qui finit par app quand on utilise le template de C::B) et les remplit très bien.
D'ailleurs, elle remplit également très bien le vecteur.
Seulement, manifestement, les données sont perdues dès que le code retourne à la méthode appelante (le programme plante sur l'accès au vecteur, et la méthode size renvoie 0).
J'ai pourtant passé le vector en référence, ce qui devrait normallement permettre la modification... D'ailleurs, j'ai même tenté d'utiliser un pointeur, avec lesquels je suis quand même plus familier, ayant passé beaucoup plus de temps à utiliser du C que du C++.
Est-ce une restriction de la STL? Je ne crois pas, j'ai créé un petit projet pour vérifier, avec 2 classes bidon qui reproduisent à peu près le même comportement sans les wxWidget (ni la bdd, avec juste un vecteur d'int en fait) et il n'y à aucun problème, le comportement est celui attendu.
Alors j'ai pensé que peut-être le fait que la classe app est, je suppose, un singleton pourrait jouer...

Si quelqu'un à compris mon roman et à une idée... Je lui serait reconnaissant de me faire partager son savoir :) (ou une suggestion pour contourner le problème)

Je quote un morceau du code incriminé: (j'ai pas vu de balise pour insérer du code?)

classeApp::PopulateList a écrit:
void logicielApp::populateList(const wxString &requete,wxControlWithItems* target ,std::vector<long*> &vect, const wxString &typped)
{
    IBPP::Database db=((logicielApp*)logicielApp::GetInstance())->database;
    std::string req=(const char*)requete.mb_str(wxConvUTF8);
    std::string nom;
    long *id;id=0;

    for(std::vector<long*>::iterator it=vect.begin();it!=vect.end();it++)
        delete *it;

    vect.clear();
    target->Clear();


    vect.push_back(0); //! permet de conserver l'index listID en phase avec celui de target
    id=new long;
    (*id)=0;
    vect.push_back(id);
    target->Append(typped); //! le texte saisi est affilié à l'index 0


    try
    {
        db->Connect();
        IBPP::Transaction tr=IBPP::TransactionFactory(db);

        tr->Start();
        IBPP::Statement st = IBPP::StatementFactory(db,tr);
        st->Execute(req);
        while(st->Fetch())
        {
            id=new long;
            *id=0;
            st->Get(1,(int*)id);
            st->Get(2,nom);
            target->Append(_U(nom.c_str()));
            vect.push_back(id);
        }
        tr->Rollback();
        db->Disconnect();

    }
    catch(IBPP::Exception& e)
    {
        wxMessageBox(wxString(e.what(), wxConvUTF8),_("Erreur!"));
    }


    target->SetSelection(0);
    //FIXME a chaque fois que la valeur change, on sélectionne la ligne 0. Forcément, c'est gênant quand on veut sélectionner le numéro 10 implémenter une interception de l'évènement qui détecte la sélection dans la liste déroulante

    #ifndef NDEBUG
    printf("\npopulatelist\n");
    for(std::vector<long*>::iterator it=vect.begin();it!=vect.end();it++)
    {
        printf("*%d=",*it);
        if(*it)
            printf("%d\n",**it);
        else
            printf("\n");
    }
    #endif

}
autre classe a écrit:
fichier h:
class TownSelect: public wxDialog
{
    public:

        TownSelect(wxWindow* parent,wxWindowID id=wxID_ANY,const wxPoint& pos=wxDefaultPosition,const wxSize& size=wxDefaultSize);
        virtual ~TownSelect();

        //(*Declarations(TownSelect)
        wxStaticText* StaticTextAreaName;
        wxComboBox* ChoiceAreaName;
        wxRadioBox* RadioBoxAreaType;
        wxStaticText* StaticTextTownName;
        wxComboBox* ComboBoxTownName;
        //*)
        std::vector<long*> idTownList,idAreaList;

    protected:

        //(*Identifiers(TownSelect)
        static const long ID_RADIOBOX1;
        static const long ID_STATICTEXTAREANAME;
        static const long ID_STATICTEXTTOWNNAME;
        static const long ID_CHOICEAREANAME;
        static const long ID_COMBOBOXTOWNNAME;
        //*)

        void FillAreaList(const wxString typped);
        void FillTownList(const wxString typped);

    private:

        //(*Handlers(TownSelect)
        void OnRadioBoxAreaTypeSelect(wxCommandEvent& event);
        void OnComboBoxTownNameSelect(wxCommandEvent& event);
        void OnChoiceAreaNameSelect(wxCommandEvent& event);
        TownSelect &operator=(const TownSelect&);
        TownSelect(const TownSelect&);
        //*)

        wxString wxreqArea,wxreqTown1,wxreqTown2,wxreqTown3;
        bool useRequest;

        DECLARE_EVENT_TABLE()
};

fichier cpp:
inline void TownSelect::FillTownList(const wxString typped)
{    wxString wxreq=wxreqTown1;
    wxreq+=typped;
    wxreq+=wxreqTown2;
    wxreq+=ChoiceAreaName->GetStringSelection();
    wxreq+=wxreqTown3;

    ((logicielApp*)logicielApp::GetInstance())->populateList(wxreq,ComboBoxTownName,idTownList,typped);
}
La classe TownSelect est l'une de celles sur lesquelles j'avais la flemme de renommer tous les noms générés par wxSmith, du coup certains ne sont pas très parlants...
Je précise aussi que j'aimerai éviter d'avoir à effectuer une requête supplémentaire en récupérant juste le label pour retrouver l'id correspondant. Effectivement, le label pourrait ne pas être toujours unique (certaines personnes ont le même nom, idem pour les communes...) et surtout, ça surchargerait le traffic réseau. Et si je voulais coder sans ce type de soucis (portabilité, code propre et qui évite de surcharger les machines), je pense que j'utiliserai quelque chose comme MFC ou .NET, avec VS ^^ (mais l'impression de pas connaître mon code me gêne avec ces derniers :P )

Voila, fin du roman ^^
Mon prochain post devrait être plus court... J'espère pour vous ;) (pour un 1er post, j'ai pas fait léger, j'en suis conscient :D )
----------
Ouai, bon, ok...
C'était une faute de frappe en fait. Une variable qui commence de la même manière que la bonne, et j'ai pas dû faire gaffe avec l'autocomplétion... Et dire que ça fait 2 jours que je suis dessus :'(

Cela dis, si quelqu'un sait comment je pourrais remplacer ces vector par une solution plus propre... Parce que séparer 2 données qui vont ensemble me plaît moyennement. Ca facilite le risque d'erreurs... d'inatention ^^

Dernière modification par freem (13-04-2010 11:57:25)

Menu forum (navigation):
Pages: 1  
 
Accueil » Accueil forums » Utilisation générale wxWidgets
» wxWidget et base de données, affilier un id à un élément d'un contrôle