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

GTK+ avec C & C++ Discussion :

Recuperer une entrée.


Sujet :

GTK+ avec C & C++

  1. #1
    Membre confirmé
    Inscrit en
    Juin 2007
    Messages
    160
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 160
    Par défaut Recuperer une entrée.
    Bonjour,

    Voilà j ai récupéré ce bout de code dans un tutoriel:

    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
    void OnUpdate(GtkWidget *entry, gpointer data)
    {
        const gchar *sText;
     
        MainWindow *pApp;
     
        /* Recuperation de data */
        pApp = (MainWindow*) data;
     
        /* Recuperation du texte contenu dans le GtkEntry */
        sText = gtk_entry_get_text(GTK_ENTRY(pApp->entry));
     
        /* Modification du texte contenu dans le GtkLabel */
        gtk_label_set_text(GTK_LABEL(pApp->pLabelAffichage1[0]), sText);
     
    }

    J aurais souhaité faire subir quelques modifications à la valeur du Gtk Entry récupéré dans cette fonction.
    Admettons que je souhaite divisé la valeur par 2 avant de l envoyer et l afficher dans le Gtk Label.

    Comment puis faire s il vous plaît.

    Mon but final serait : l utilisateur saisi une valeur dans un gtk_spin_button_new_with_range, il appuis sur un pButton (qui s appel "calcul"), ce qui déclencheras l affichage de plusieurs résultats dans plusieurs Gtk Label.

    Merci par avance de vos réponses.

    Shazad.

  2. #2
    Membre Expert
    Homme Profil pro
    Inscrit en
    Janvier 2005
    Messages
    1 259
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 1 259
    Par défaut
    Ta question concerne donc spécifiquement comment convertir entre un entier et une chaîne ? Il y a des posts de forum à ce sujet, en gros tu peux utiliser strtol/g_strdup_printf

  3. #3
    Membre confirmé
    Inscrit en
    Juin 2007
    Messages
    160
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 160
    Par défaut
    Bonjour teuf13,

    Merci pour ta réponse.
    Comme mon gtk spin button autorise la saisi de valeurs avec des nombres à virgules, il va falloir que je convertis le const gchar en double ou gdouble.

    J ai trouvé ceci pour l instant en m aidant de la documentation GTK:

    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
    void OnUpdate(GtkWidget *entry, gpointer data)
    {
        const gchar *sText;
        gdouble diapason;
     
        MainWindow *pApp;
     
        /* Recuperation de data */
        pApp = (MainWindow*) data;
     
        /* Recuperation du texte contenu dans le GtkEntry */
        sText = gtk_entry_get_text(GTK_ENTRY(pApp->entry));
     
        diapason = g_ascii_strtod(const gchar *sText, gchar **endptr);
     
        /* Modification du texte contenu dans le GtkLabel */
        gtk_label_set_text(GTK_LABEL(pApp->pLabelAffichage1[0]), sText);
     
    }
    Je ne comprend pas ce qu est le second paramètre (gchar **endptr) dans g_ascii_strtod.
    Le compilateur me montre une erreur:
    syntax error before "const".
    Je me trompe peut être dans l utilisation de cet fonction.


    Shazad

  4. #4
    Modérateur

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2009
    Messages
    1 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 395
    Par défaut
    Je pense que tu devrais relire tes cours de C sur comment appeler une fonction, avant de chercher à bidouiller en GTK. On n'apprend pas à courir avant d'avoir appris à marcher...

    Sur un appel de fonction, tu passes juste le nom du paramètre, tu ne remets pas son type.
    Code incorrect :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    diapason = g_ascii_strtod(const gchar *sText, gchar **endptr);
    Code correct : (si endptr a été déclaré)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    diapason = g_ascii_strtod(sText, endptr);
    La documentation de g_ascii_strtod t'indique explicitement que si ce n'est pas pour relire quelque chose qui est forcément en ascii, tu devrait utiliser la fonction strtod de la libc.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    gchar *end = NULL;
    diapason = strtod(sText, &end);
    Si tu ne souhaites pas gérer les erreurs pour l'instant (c'est mal !), mais tu peux écrire plus simplement:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    diapason = strtod(sText, NULL);
    Pour le fonctionnement de strtod, il suffit de lire la page de manuel associée :
    http://www.linux-kheops.com/doc/man/.../strtod.3.html
    endptr te permet de faire une partie de la détection d'erreur. Il contient l'adresse du caractère qui suit le dernier caractère à avoir pu être traité.
    En gros si la chaine est "18toutous", endptr contiendra l'adresse du premier 't'.

  5. #5
    Membre confirmé
    Inscrit en
    Juin 2007
    Messages
    160
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 160
    Par défaut
    Bonjour libeforce,

    Il est vrai que j essais de créer une interface graphique sans réellement avoir toutes les cartes en main. Mon code est quand même bien avancé et il est vrai que je suis à un moment difficile.
    Je peux comprendre comment cela peux agacer les personnes du forum avec des messages comme le mien, mais je t avoue que je n ai jamais appris à programmer dans un cursus scolaire ou autre, et je t avoue aussi qu'il est difficile de bien progresser dans la programmation quand on a pas le vocabulaire nécessaire et que personne autour peux aider. Alors j essais de ne pas m empêcher de faire des choses et il est vrai que je compte beaucoup sur la communauté des personnes de ce forum.
    En tous les cas tous les conseils que l on me donne ne sont pas vain car cela me fait progresser à chaque fois.

    Je me permet de poser encore une question:

    Si je veux maintenant envoyer "diapason" à gtk_label_set_text , est-ce que je dois utiliser g_ascii_dtostr ?

    Encore merci par avance.

    Shazad

  6. #6
    Membre Expert
    Homme Profil pro
    Inscrit en
    Janvier 2005
    Messages
    1 259
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 1 259
    Par défaut
    Nope, plutôt le g_strdup_printf que je t'ai indiqué précédemment (ça fonctionne comme printf). Par contre n'oublie pas de libérer la valeur qu'il retourne après utilisation si tu ne veux pas de fuite de mémoire.

  7. #7
    Membre confirmé
    Inscrit en
    Juin 2007
    Messages
    160
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 160
    Par défaut
    Merci teuf13, je vais essayer de mettre en oeuvre ce que tu me dis.

    Shazad

  8. #8
    Modérateur

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2009
    Messages
    1 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 395
    Par défaut
    Citation Envoyé par teuf13 Voir le message
    Nope, plutôt le g_strdup_printf que je t'ai indiqué précédemment (ça fonctionne comme printf). Par contre n'oublie pas de libérer la valeur qu'il retourne après utilisation si tu ne veux pas de fuite de mémoire.
    Faut voir... Déjà, je ne connaissais pas du tout g_ascii_dtostr... Mais il a l'air plus pratique ici, pas besoin d'allouer/désallouer de mémoire dans le tas, on peut utiliser directement un tableau dans la pile.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    gchar strdiapason[G_ASCII_DTOSTR_BUF_SIZE];
    diapason = g_ascii_strtod (sText, NULL);
    /* A présent on incrémente avant de la mettre dans le GtkLabel */
    diapason++; 
    g_ascii_dtostr (strdiapason, sizeof (strdiapason), diapason);
    gtk_label_set_text(GTK_LABEL(pApp->pLabelAffichage1[0]), strdiapason);
    Après la seule réserve que j'ai, c'est que le séparateur décimal est forcément un point (et donc n'utilise pas celui de la locale - c'est à dire la virgule en français)...

  9. #9
    Membre Expert
    Homme Profil pro
    Inscrit en
    Janvier 2005
    Messages
    1 259
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 1 259
    Par défaut
    Oui, déjà ça renvoie un nombre avec un ".", pas une "," si nécessaire, et là c'est un peu comme recommander sprintf ou snprintf au lieu de g_strdup_printf. Ca peut être mieux dans certains cas, mais c'est plus dangereux. En plus, g_strdup_printf a l'avantage d'être beaucoup plus versatile et de pouvoir être réutilisé dans d'autres situations.

  10. #10
    Membre confirmé
    Inscrit en
    Juin 2007
    Messages
    160
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 160
    Par défaut
    Bonjour,

    Je viens d essayer ton code libeforce, il fonctionne bien, mais il m arrive juste un petit souci:

    le Gtk entry que j utilise est un gtk_spin_button_new_with_range auquel j ai donné ceci comme valeur (0, 2000, 0.01).

    Quand je compile, l interface se lance, j incrémente avec les flèches du gtk_spin_button_new_with_range, je met une valeur de 4.72 par exemple et quand j appuis sur mon bouton calcul, il s affiche le nombre 5 dans le Gtk Label.

    En fait tous les nombres du gtk_spin_button_new_with_range sont arrondis au nombre supérieur.

    Est-ce le fait d avoir utilisé un gtk_spin_button_new_with_range avec la possibilitée de mettre un chiffre à virgule qui engendre ceci ?

    Voulez vous mon code complet ?

    Shazad

  11. #11
    Membre confirmé
    Inscrit en
    Juin 2007
    Messages
    160
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 160
    Par défaut
    J ai le même souci avec un gtk_entry_new(). Toutes les valeurs entrées ne sont pas toujours bien affiché.
    Par exemple 12.36 devient 12.35999999999 dans le Gtk Label.

    Shazad

  12. #12
    Membre confirmé
    Inscrit en
    Juin 2007
    Messages
    160
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 160
    Par défaut
    J aurais voulu avoir votre avis sur le fait de récupérer la valeur du gtk_spin_button_new_with_range dans le main avec gtk_spin_button_get_value
    et l enoyer dans la fonction afin de pouvoir traiter cette valeur.

    Peut être existe il un autre widget que Gtk Label pour afficher mon résultat.

    Shazad

  13. #13
    Membre Expert
    Homme Profil pro
    Inscrit en
    Janvier 2005
    Messages
    1 259
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 1 259
    Par défaut
    12.36 qui devient 12.35999, ça vient de la façon dont les nbs flottants sont stockés, il ne doit pas y avoir de manière exacte de stocker 12.36 dans un flottant, donc tu récupères une valeur proche. Pour le 4.72 qui se "transforme" en 5, tu peux mettre des g_print tout au long de la conversion de ton entier en chaîne pour comprendre à quel moment tu perds de l'information.

  14. #14
    Membre confirmé
    Inscrit en
    Juin 2007
    Messages
    160
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 160
    Par défaut
    Voilà les erreurs que je récupère dans la console:



    Je pense que j ai déjà un premier problème avec la façon dont j ai codé mon interface avant celui de la conversion.

    Shazad

  15. #15
    Membre confirmé
    Inscrit en
    Juin 2007
    Messages
    160
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 160
    Par défaut
    Peut être que pour mon problème de conversion je dois utiliser g_local_to_utf8.

    Shazad

  16. #16
    Membre confirmé
    Inscrit en
    Juin 2007
    Messages
    160
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 160
    Par défaut
    Voilà comment j ai utilisé g_print:

    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
    const gchar *sText;
        double diapason;
        MainWindow *pApp;
     
     
     
        pApp = (MainWindow*) data;
     
     
        sText = gtk_entry_get_text(GTK_ENTRY(pApp->entry));
     
        g_print ("%lf \n", sText);
     
        gchar strdiapason[G_ASCII_DTOSTR_BUF_SIZE];
     
        g_print("%lf \n", strdiapason);
     
        diapason = g_ascii_strtod (sText, NULL);
     
        g_print("%lf \n", diapason);
     
     
     
     
        diapason++;
        g_ascii_dtostr (strdiapason, sizeof (strdiapason), diapason);
     
        gtk_label_set_text(GTK_LABEL(pApp->pLabelAffichage1[0]), strdiapason);
    dans la console , je n ai que des résultats comme cela, si je met dans le spin button par exemple : 2,36.

    0,000000
    0,000000
    2,000000

    Pour le g_print sur sText et strdiapason le compilateur me met un avertissement. (double format).

    Shazad

  17. #17
    Expert confirmé
    Avatar de gerald3d
    Homme Profil pro
    Conducteur de train
    Inscrit en
    Février 2008
    Messages
    2 308
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Conducteur de train
    Secteur : Transports

    Informations forums :
    Inscription : Février 2008
    Messages : 2 308
    Billets dans le blog
    5
    Par défaut
    sText est unun gchar* donc il faut utiliser l'argument %s en lieu est place de %lf.

    La déclaration de strdiapason est un tableau d'entiers signés sur un 1 octet. Comme ce tableau n'est pas initialisé, tu ne peux pas l'afficher comme ca.

    Pour afficher diapason je ferai plutôt:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    g_print("%.2f", diapason);
    . Regarde ce lien qui explique quels formats tu peux utiliser pour l'affichage de tes données.

    edit: J'ai confondu vitesse et précipitation . J'ai rectifié le message avec le lien en question.

  18. #18
    Modérateur

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2009
    Messages
    1 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 395
    Par défaut
    Citation Envoyé par teuf13 Voir le message
    Oui, déjà ça renvoie un nombre avec un ".", pas une "," si nécessaire, et là c'est un peu comme recommander sprintf ou snprintf au lieu de g_strdup_printf. Ca peut être mieux dans certains cas, mais c'est plus dangereux. En plus, g_strdup_printf a l'avantage d'être beaucoup plus versatile et de pouvoir être réutilisé dans d'autres situations.
    Comme je l'ai dit, l'argument sur le séparateur décimal est recevable. Mais tu te fourvoies en pensant que g_strdup_printf est la panacée et à utiliser dans 100% des cas. Surtout en parlant de dangerosité. Oui, sprintf permet des buffer overflow car il ne vérifie pas que le buffer où il écrit est assez grand, et peut être à l'origine de failles de sécurité.

    Mais snprintf n'a pas ce problème, il n'y a aucune raison de lui cracher dessus. Au pire, il tronque la sortie, ce qui est un autre problème...

    Sauf que... g_ascii_dtostr n'a pas ce problème, car on te garantit qu'il ne sera jamais écrit plus G_ASCII_DTOSTR_BUF_SIZE octets dans la chaîne finale. Tu as donc moyen d'allouer un buffer de ce type en toute sécurité, avec des performances meilleures qu'en allouant une chaîne dans le tas, et sans aucun risque de fuite mémoire.

    Le seul désavantage que je vois au final est celui du séparateur décimal, mais inutile d'accabler cette fonction de tous les maux du monde sans raison...

  19. #19
    Membre Expert
    Homme Profil pro
    Inscrit en
    Janvier 2005
    Messages
    1 259
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 1 259
    Par défaut
    Ah oui pardon, j'oubliais que 100% des programmeurs sur terre savaient coder parfaitement et connaissaient sur le bout des doigts toutes les subtilités d'allocations mémoire/buffer overflow/... possibles en C et que personne ne se tromperait jamais en oubliant d'allouer le tableau, ou en allouant un tableau à la mauvaise taille, .... Mais où avais-je la tête!

  20. #20
    Modérateur

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2009
    Messages
    1 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 395
    Par défaut
    Citation Envoyé par shazad Voir le message
    Voilà comment j ai utilisé g_print:

    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
    const gchar *sText;
        double diapason;
        MainWindow *pApp;
     
     
     
        pApp = (MainWindow*) data;
     
     
        sText = gtk_entry_get_text(GTK_ENTRY(pApp->entry));
     
        g_print ("%lf \n", sText);
     
        gchar strdiapason[G_ASCII_DTOSTR_BUF_SIZE];
     
        g_print("%lf \n", strdiapason);
     
        diapason = g_ascii_strtod (sText, NULL);
     
        g_print("%lf \n", diapason);
     
     
     
     
        diapason++;
        g_ascii_dtostr (strdiapason, sizeof (strdiapason), diapason);
     
        gtk_label_set_text(GTK_LABEL(pApp->pLabelAffichage1[0]), strdiapason);
    dans la console , je n ai que des résultats comme cela, si je met dans le spin button par exemple : 2,36.

    0,000000
    0,000000
    2,000000

    Pour le g_print sur sText et strdiapason le compilateur me met un avertissement. (double format).

    Shazad
    Il y a plusieurs erreurs:

    1. Tu dois apprendre les spécificateurs de format des fonctions de type printf. Par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    g_print ("%lf \n", sText);
    n'est pas correct, car avec %lf tu demandes d'afficher un long float (= un double), alors que tu passes en paramètre une chaîne de caractère... Les types ne correspondent pas. Ceci est correct. %s désigne une string (= une chaine de caractère)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    g_print ("%s \n", sText);
    2. Tu tentes d'afficher un buffer non initialisé.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
        gchar strdiapason[G_ASCII_DTOSTR_BUF_SIZE];
        g_print("%lf \n", strdiapason);
        diapason = g_ascii_strtod (sText, NULL);
        g_print("%lf \n", diapason);
        diapason++;
        g_ascii_dtostr (strdiapason, sizeof (strdiapason), diapason);
    Tu crées un tableau de caractères, mais tu ne l'as pas initialisé. Au mieux, ton compilateur aura mis à 0 chaque octet du tableau à la déclaration, au pire, tu vas te retrouver avec une valeur au hasard, qui dépendra du ce qu'il y avait en mémoire à l'emplacement où ton tableau a été alloué. Tu refais ensuite la même erreur qu'au (1).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
        gchar strdiapason[G_ASCII_DTOSTR_BUF_SIZE];
        diapason = g_ascii_strtod (sText, NULL);
        g_print("%lf \n", diapason);
        diapason++;
        g_ascii_dtostr (strdiapason, sizeof (strdiapason), diapason);
        g_print("%s\n", strdiapason);
    Pour les spécifications de format (%d = entier signés, %s pour les chaines, etc.), voir le manuel de printf.

    Je pense aussi que tu devrais poster dans la section "C" du forum, plutôt que dans la section GTK. Jusqu'à présent, aucun de tes problèmes n'a concerné GTK, ce sont juste des problèmes de base en C. Mais c'est en forgeant qu'on devient forgeron...

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Recuperer une entrée par rapport a sa date
    Par bastian06n dans le forum Requêtes
    Réponses: 5
    Dernier message: 02/09/2010, 16h36
  2. Recuperer une entrée utilisateur
    Par batama dans le forum Scripts/Batch
    Réponses: 3
    Dernier message: 25/09/2008, 13h51
  3. [SAX] Recuperer une chaine XML entre balises avec SAX
    Par Ange-Louis dans le forum Format d'échange (XML, JSON...)
    Réponses: 3
    Dernier message: 01/08/2008, 10h33
  4. [Stratégie] Récupérer une instance existante
    Par cmoulin dans le forum Général Java
    Réponses: 14
    Dernier message: 11/05/2004, 15h48
  5. comment recuperer une variable dans flash
    Par krépuscul dans le forum Flash
    Réponses: 30
    Dernier message: 16/10/2003, 09h40

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