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 :

pb g_signal_connect, mise à jour du 4è argument user_data


Sujet :

GTK+ avec C & C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Développeur Web en Loisir
    Inscrit en
    Janvier 2006
    Messages
    129
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web en Loisir

    Informations forums :
    Inscription : Janvier 2006
    Messages : 129
    Par défaut pb g_signal_connect, mise à jour du 4è argument user_data
    bonsoir,

    J'ai connecté un signal ainsi pour réaliser un drag qui marche parfaitement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    g_signal_connect (G_OBJECT ((*plane).label), "motion-notify-event", G_CALLBACK (on_motion_notify_event_cb), plane);
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    static gboolean on_motion_notify_event_cb (GooCanvasItem *item, GooCanvasItem *target_item, GdkEventMotion *event, gpointer plane) {
     .....
        canvas_connect_item(plane);
      ......
    }
    Mais le signal est connecté avec la valeur de plane au moment de cette connection. Or plane, qui est une structure, change au cours du temps et donc dans le callback sa valeur est celle du début et non celle à l'instant t.

    Comment faire alors pour avoir dans le callback la valeur de plane à l'instant t ??

  2. #2
    Membre éclairé
    Profil pro
    Retraité
    Inscrit en
    Novembre 2009
    Messages
    331
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Novembre 2009
    Messages : 331
    Par défaut
    Si tu passe un pointeur sur la structure au lieu de la structure elle même (ce qui est meilleur du point de vue des performances), tu aura alors accès aux valeurs des éléments à l'instant où le callback est exécuté.

  3. #3
    Membre confirmé
    Homme Profil pro
    Développeur Web en Loisir
    Inscrit en
    Janvier 2006
    Messages
    129
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web en Loisir

    Informations forums :
    Inscription : Janvier 2006
    Messages : 129
    Par défaut
    bonjour,

    Autant pour moi plane est déjà un pointeur sur structure et ça ne fonctionne pas.

    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
    typedef struct
    {
        char callsign[8];
        char actype[5];
        char departure[5];
        char arrival[5];
        double rfl;
        double pfl;
        double xfl;
        double afl;
        double cfl;
        // tableau de x chaines dont la longueur fait 5 caractères (x étant inconnu au départ) : char (*route)[6]
        s_waypoint *route;
        double x;
        double y;
        double tx;
        double ty;
        double dtaBeforeX;
        double dtaBeforeY;
        double dtaAfterX;
        double dtaAfterY;
        double inclinaisonStd;
        int currentSegment;
        double turnDirection;
        _Bool turn;
        _Bool onHdg;
        char *hdg;
        double heading;
        double targetHdg;
        double groundSpd;
        GooCanvasItem *plot;
        GooCanvasItem *label;
        GooCanvasItem *connection;
        double labelx;
        double labely;
    } s_plane;
    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
    void plane_constructor(s_plane *plane, int nb_fixes, ...) {
        /* ----construction route --- nb paramètres inconnus = nb_fixes = 5 ici ----*/
        (*plane).route = malloc(nb_fixes*sizeof(*(*plane).route));
        int i=0, j=0;
        va_list ap;
        va_start(ap, nb_fixes);
        for( i=0 ; i<nb_fixes ; i++) {
            strcpy((*plane).route[i].wp_nom, va_arg(ap, char *));
            for (j=0; j<nb_wp; j++) {
                if (strcmp((*plane).route[i].wp_nom, waypoints[j].wp_nom) == 0) {
                    (*plane).route[i].wp_x = waypoints[j].wp_x;
                    (*plane).route[i].wp_y = waypoints[j].wp_y;
                    (*plane).route[i].wp_cercle = NULL;
                    (*plane).route[i].wp_label = NULL;
                    break;
                }
            }
        }
        va_end(ap);
    
        (*plane).x = (*plane).route[0].wp_x;
        (*plane).y = (*plane).route[0].wp_y;
        (*plane).inclinaisonStd = 30.0;
        (*plane).currentSegment = 0;
        (*plane).turnDirection = 1;
        (*plane).turn = FALSE;
        (*plane).onHdg = FALSE;
        (*plane).hdg = (*plane).route[0].wp_nom;
        (*plane).heading = trueRoute((*plane).x, (*plane).y, (*plane).route[1].wp_x, (*plane).route[1].wp_y);
        (*plane).plot = goo_canvas_ellipse_new (root, (*plane).x, (*plane).y, 3.0, 3.0,
                                                     "stroke-color", "white",
                                                     "line-width", 2.0,
                                                     "fill-color", "white",
                                                     NULL);
    
       
        (*plane).labelx = (*plane).x + 20.0;
        (*plane).labely = (*plane).y + 20.0;
        (*plane).label = goo_canvas_text_new (root, (*plane).callsign, (*plane).labelx, (*plane).labely, 100.0, GOO_CANVAS_ANCHOR_SW,
                                               "fill-color", "white", "font", "Arial 12px",
                                               NULL);
        coord.x = (*plane).x;
        coord.y = (*plane).y;
        g_signal_connect (G_OBJECT ((*plane).label), "button-press-event", G_CALLBACK (on_button_press_event_cb), NULL);
        g_signal_connect (G_OBJECT ((*plane).label), "button-release-event", G_CALLBACK (on_button_release_event_cb), NULL);
        g_signal_connect (G_OBJECT ((*plane).label), "motion-notify-event", G_CALLBACK (on_motion_notify_event_cb), plane);
    
        GooCanvasBounds label_bounds;
    	goo_canvas_item_get_bounds((*plane).label, &label_bounds);
    
    	(*plane).connection = goo_canvas_polyline_new_line(root, (*plane).x, (*plane).y, label_bounds.x1, label_bounds.y1,
                                         "line-width", 1.0, "stroke-color", "white", NULL);
    
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    void canvas_connect_item(s_plane *plane) {
    	goo_canvas_item_remove((*plane).connection);
    	GooCanvasBounds label_bounds;
    	goo_canvas_item_get_bounds((*plane).label, &label_bounds);
     
    	(*plane).connection = goo_canvas_polyline_new_line(root, (*plane).x, (*plane).y, label_bounds.x1, label_bounds.y1,
                                         "line-width", 1.0, "stroke-color", "white", NULL);
    }
    dans le main :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    s_plane avion1 = { "SWR422", "B777", "LSGG", "SKBO", 360, 360, 360, 360, 360};
      plane_constructor(&avion1, 5, "MTL2", "MTL", "GRENA", "LTP", "RAPID");
    C'est (*plane).x (*plane).y (position de l'élément (*plane).plot) qui changent toutes les 4 secondes et quand je drag (*plane).label, j'ai besoin de (*plane).x et (*plane).y pour retracer ma ligne (dans connect item) entre (*plane).plot et (*plane).label.

    Malheureusement, au moment du drag (*plane).x et (*plane).y valent la valeur qu'ils avaient au départ et non la valeur à l'instant t.
    Du coup je ne sais pas comment faire ?

  4. #4
    Membre éclairé
    Profil pro
    Retraité
    Inscrit en
    Novembre 2009
    Messages
    331
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Novembre 2009
    Messages : 331
    Par défaut
    Petite remarque: il est inhabituel d'écrire (*plane).x car la notation plane->x a été définie pour améliorer la lisibilité.

    Je ne comprends pas très bien si c'est la valeur des éléments qui composent "plane" qui varie ou bien si, parce que tu as plusieurs réalisations de la structure "plane", le pointeur change.
    Dans le premier cas, il suffit de déclarer le pointeur static pour conserver sa valeur entre deux appels (à condition de ne pas faire de nouvelle allocation ou reallocation entre temps), dans le second, il te faut envisager un niveau d'indirection supplémentaire, par exemple un tableau ou une liste, pour choisir la bonne structure.

  5. #5
    Membre confirmé
    Homme Profil pro
    Développeur Web en Loisir
    Inscrit en
    Janvier 2006
    Messages
    129
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web en Loisir

    Informations forums :
    Inscription : Janvier 2006
    Messages : 129
    Par défaut
    Merci pour ta réponse.
    En fait ce sont les 2 cas mais dans un premier temps je ne m'occupe que du cas n°1, où les valeurs de la structure changent toutes les 4s à l'aide d'un timer :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    void start_timer(GtkWidget *button, gpointer data) {
        if (timer == 0) {
            timer = g_timeout_add(gameSpeed, (GSourceFunc) doroute, (gpointer) &fleet[0]);
        } else {
            g_print("Un timer est deja en route");
        }
        g_print("timer id: %d", timer);
    }
    C'est la fonction doroute qui change les valeurs de la structure.

    avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    static s_plane fleet[30];
    qui est défini au début du programme.

    J'ai suivi ton indication en rajoutant static devant la définition d'avion dans le main. Mais cela ne change rien. Je crois que y'a un truc que j'ai pas compris ??
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    static s_plane avion1 = { "SWR422", "B777", "LSGG", "SKBO", 360, 360, 360, 360, 360};
      plane_constructor(&avion1, 5, "MTL2", "MTL", "GRENA", "LTP", "RAPID");
    fleet[0] = avion1;

  6. #6
    Membre confirmé
    Homme Profil pro
    Développeur Web en Loisir
    Inscrit en
    Janvier 2006
    Messages
    129
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web en Loisir

    Informations forums :
    Inscription : Janvier 2006
    Messages : 129
    Par défaut précision
    Je précise que les valeurs (*plane)->x et (*plane)->y sont bien modifiées et 'gardées' au cours du programme.

    Le problème arrive quand je drag avec la souris pour déclencher le 'motion-event' car à ce moment là (*plane)->x et (*plane)->y retrouve momentanément la valeur qu'ils avaient au départ lors de l'appel à g_signal_connect. Lorsque je relache la souris, les valeurs (*plane)->x et (*plane)->y retrouvent leurs valeurs calculées d'avant le drag.

    PS : merci pour la remarque, je viens du monde javascript ou le point est utilisé, c'est pourquoi j'utilisais cette notation plutôt que l'autre

    je vais essayer de poster des screenshots

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

Discussions similaires

  1. Mise à jour DataBase sur base du DataSet et Erreur Arguments trop nombreux
    Par Rifton007 dans le forum Accès aux données
    Réponses: 3
    Dernier message: 26/03/2009, 20h55
  2. [mise à jour]Comment procéder sans tout péter...
    Par FFF dans le forum Installation
    Réponses: 3
    Dernier message: 10/09/2003, 08h11
  3. Mise à jour de la version de MySQL
    Par jobstar dans le forum Administration
    Réponses: 8
    Dernier message: 18/08/2003, 10h45
  4. mise à jour de champs time (interbase)
    Par pram dans le forum XMLRAD
    Réponses: 6
    Dernier message: 04/03/2003, 10h25
  5. Réponses: 2
    Dernier message: 12/02/2003, 15h26

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