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 :

Modifier puis passer des données à un widget (menu item) à l'exécution


Sujet :

GTK+ avec C & C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Géomaticien
    Inscrit en
    Février 2010
    Messages
    63
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Géomaticien

    Informations forums :
    Inscription : Février 2010
    Messages : 63
    Par défaut Modifier puis passer des données à un widget (menu item) à l'exécution
    Salut,

    J'ai crée pour mon programme un popup menu qui s'ouvre d'un clic droit sur chacun de mes widgets (mes petites boiboites, n'est-ce pas liberforce ). Pour des raisons pratiques et d'économie de mémoire, j'ai crée un unique popup pour tous les widgets ainsi qu'une unique callback pour tous les menu item, le widget cliqué est justement déterminé au moment du clic pour le distinguer et ainsi modifier en concordance le popup menu. Le souci est que chaque widget contient d'autres données et il faut les passer au popup menu qui agira en fonction du menu item cliqué par l'utilisateur.

    Pour corser un peu le tout, je préfère utiliser des pointeurs de fonctions qui seront indiqués par une partie externe à ce bloc (où j'y dessine mes widgets), ceci afin de bien séparer mon code des données (comme tu m'as conseillé, liberforce ) pour par exemple utiliser ce code dans d'autres programmes sans avoir à le modifier.

    Je ne peux pas passer les données au moment de la connexion du signal car justement cela dépend du widget cliqué par l'utilisateur. Je dois au maximum éviter d'utiliser des variables globales. J'ai pensé à connecter le signal du widget au moment du clic droit, ce qui me permet de modifier les menus item sans encombrer le conteneur de données (le gpointer data), le problème est je crois ne plus pouvoir modifier par la suite le conteneur de données, si je ne me trompe pas. J'ai pensé à déconnecter le signal du widget à chaque fois que l'action est terminée mais je n'ai pas trouvé de telle fonction.

    Une idée ? Une piste ?
    Merci.

  2. #2
    Membre averti
    Homme Profil pro
    Géomaticien
    Inscrit en
    Février 2010
    Messages
    63
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Géomaticien

    Informations forums :
    Inscription : Février 2010
    Messages : 63
    Par défaut
    OK, bon j'ai trouvé comment déconnecter un signal :

    http://library.gnome.org/devel/gobje...ler-disconnect

    Mais ça m'oblige à stocker les menu items en variable globale

  3. #3
    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
    Hello,
    bon, je n'ai pas tout compris, est-ce que tu pourrais montrer les bouts de code en question stp ?

  4. #4
    Membre averti
    Homme Profil pro
    Géomaticien
    Inscrit en
    Février 2010
    Messages
    63
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Géomaticien

    Informations forums :
    Inscription : Février 2010
    Messages : 63
    Par défaut
    Alors, oui, je peux passer le code en l'état, càd en passant par des variables globales. Cependant, je n'ai pas essayé si ça marche, mais j'espère que ça t'aidera à comprendre ce que je veux faire. J'y ai placé quelques commentaires.


    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
     
    /* Ici la structure du popup menu */
    typedef struct
    {
        GtkMenu             *mnuPatch;
        GtkMenuItem         *mnuitmPatchName;
     
        GtkImageMenuItem    *mnuitmPatchInfo;
        GFunc               info_func;
        gulong              handler_info;
     
        GtkImageMenuItem    *mnuitmPatchProp;
        GFunc               prop_func;
        gulong              handler_prop;
     
        GtkImageMenuItem    *mnuitmDelPatch;
        GFunc               del_func;
        gulong              handler_del;
    } stPopup;
     
    static stPopup  *PopupMenu = NULL;

    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
    static void
    box_popupmenu_build ()
    {
    /* fonction de construction du popup menu */
        if (PopupMenu == NULL)
        {
            PopupMenu=g_slice_new(stPopup);
     
            PopupMenu->mnuPatch = GTK_MENU (gtk_menu_new ());
            PopupMenu->mnuitmPatchName = GTK_MENU_ITEM (gtk_menu_item_new_with_label (""));
            gtk_widget_set_sensitive (GTK_WIDGET (PopupMenu->mnuitmPatchName), FALSE);
     
            PopupMenu->mnuitmPatchInfo = GTK_IMAGE_MENU_ITEM (gtk_image_menu_item_new_with_label (GTK_STOCK_INFO));
            PopupMenu->mnuitmPatchProp = GTK_IMAGE_MENU_ITEM (gtk_image_menu_item_new_with_label (GTK_STOCK_PROPERTIES));
            PopupMenu->mnuitmDelPatch = GTK_IMAGE_MENU_ITEM (gtk_image_menu_item_new_with_label (GTK_STOCK_DELETE));
     
            gtk_image_menu_item_set_use_stock (PopupMenu->mnuitmPatchInfo, TRUE);
            gtk_image_menu_item_set_use_stock (PopupMenu->mnuitmPatchProp, TRUE);
            gtk_image_menu_item_set_use_stock (PopupMenu->mnuitmDelPatch, TRUE);
     
            gtk_menu_shell_append (GTK_MENU_SHELL (PopupMenu->mnuPatch), GTK_WIDGET (PopupMenu->mnuitmPatchName));
            gtk_menu_shell_append (GTK_MENU_SHELL (PopupMenu->mnuPatch), gtk_separator_menu_item_new());
            gtk_menu_shell_append (GTK_MENU_SHELL (PopupMenu->mnuPatch), GTK_WIDGET (PopupMenu->mnuitmPatchInfo));
            gtk_menu_shell_append (GTK_MENU_SHELL (PopupMenu->mnuPatch), GTK_WIDGET (PopupMenu->mnuitmPatchProp));
            gtk_menu_shell_append (GTK_MENU_SHELL (PopupMenu->mnuPatch), GTK_WIDGET (PopupMenu->mnuitmDelPatch));
     
            gtk_widget_show_all (GTK_WIDGET (PopupMenu->mnuPatch));
        }
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    static void
    box_functions_popmenu (GFunc Info_Func, GFunc Prop_Func, GFunc Del_Func) 
     
    {
    /* ici cela me permet de pointer les fonctions de l'application qui permettront aux menu
        item de les appeler. */
    /* C'est le seul moyen que j'ai trouvé pour séparer mon code de représentation avec des
        box de celui contenant/manipulant réellement les données */
        PopupMenu->info_func = Info_Func;
        PopupMenu->prop_func = Prop_Func;
        PopupMenu->del_func = Del_Func;
    }
    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
    static void
    box_on_mouse_button_press (GooCanvasItem *Item,
                                     GooCanvasItem *Target,
                                     GdkEventButton *MouseEvent,
                                                   gpointer data)
    {
    /* Fonction lorsque je clique bouton droit sur la Box ; le pointeur data pointe sur la
        donnée du type stBox représenté par la Box */
        switch (MouseEvent->button)
        {
     
            case 3:
                gtk_menu_item_set_label (PopupMenu->mnuitmPatchName,
                                         box_get_name (BOX (data)));
     
                PopupMenu->handler_info = g_signal_connect (PopupMenu->mnuitmPatchInfo,
                                                           "activate",
                                                           G_CALLBACK (on_menu_Item_activate), data);
                PopupMenu->handler_prop = g_signal_connect (PopupMenu->mnuitmPatchProp,
                                                           "activate",
                                                           G_CALLBACK (on_menu_Item_activate), data);
                PopupMenu->handler_del = g_signal_connect (PopupMenu->mnuitmDelPatch,
                                                          "activate",
                                                          G_CALLBACK (on_menu_Item_activate), data);
     
                gtk_menu_popup (PopupMenu->mnuPatch,
                                NULL,
                                NULL,
                                NULL,
                                data,
                                2,
                                MouseEvent->time);
     
                break;
        }
    }
    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
    static void
    on_menu_Item_activate (GtkMenuItem *MenuItem, gpointer data)
    {
    /* ici le code lors du clic dans les menus items */
        GtkWindow *Instance = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (MenuItem)));
     
        if (g_strcmp0 (gtk_menu_item_get_label (MenuItem), GTK_STOCK_INFO) == 0)
        {
            (*PopupMenu->info_func) (data, NULL);
            g_signal_handler_disconnect (Instance, PopupMenu->handler_info);
        }
        else if (g_strcmp0 (gtk_menu_item_get_label (MenuItem), GTK_STOCK_PROPERTIES) == 0)
        {
            (*PopupMenu->prop_func) (data, NULL);
            g_signal_handler_disconnect (Instance, PopupMenu->handler_prop);
        }
        else if (g_strcmp0 (gtk_menu_item_get_label (MenuItem), GTK_STOCK_DELETE) == 0)
        {
            (*PopupMenu->del_func) (data, NULL);
            g_signal_handler_disconnect (Instance, PopupMenu->handler_del);
        }
    }

  5. #5
    Membre averti
    Homme Profil pro
    Géomaticien
    Inscrit en
    Février 2010
    Messages
    63
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Géomaticien

    Informations forums :
    Inscription : Février 2010
    Messages : 63
    Par défaut
    Je viens de me rendre compte qu'il y aura un problème : lorsque l'utilisateur ne clique pas sur un menu item et donc annule son action, le signal n'est pas déconnecté. On revient à mon problème de départ. Mais peut-être dois-je poser la question différemment : est-ce que connecter un signal plusieurs fois sur un même widget sans le déconnecter auparavant pose-t-il un problème ?

  6. #6
    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
    Je répondrai sans trop réfléchir non. Il m'arrive de connecter plusieurs callbacks différents avec le même signal dans un GtkDrawingArea sans aucun problème.
    Il existe d'ailleurs la fonction g_signal_connect_after(); qui le dit implicitement. Cette fonction donne un ordre dans l'appel des différents callback pour un même signal.

Discussions similaires

  1. passer des données a une autre page php
    Par questionneuse dans le forum Langage
    Réponses: 10
    Dernier message: 25/01/2006, 00h56
  2. [Debutant] comment faire passer des donnée ???
    Par cyrill.gremaud dans le forum AWT/Swing
    Réponses: 1
    Dernier message: 17/01/2006, 22h28
  3. [VB6] passer des données de VB vers un fichier Word
    Par Eba chan dans le forum VB 6 et antérieur
    Réponses: 1
    Dernier message: 04/01/2006, 17h55
  4. [Données]Passer des données entre applet et Servlet
    Par CheryBen dans le forum Applets
    Réponses: 11
    Dernier message: 16/09/2005, 13h48
  5. Réponses: 6
    Dernier message: 16/09/2005, 10h56

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