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

Contribuez Discussion :

Les menus avec et sans glade


Sujet :

Contribuez

  1. #1
    Rédacteur/Modérateur

    Les menus avec et sans glade
    Bonjour

    Est-ce vous pensez qu'il serait une bonne idée de développer mon pense-bête que je complète petit à petit pour en faire un article :

    1) Mettre une fenêtre «*Niveaux supérieurs->Fenêtres*» («*Toplevels->Window*») sur l'écran principal.
    2) Poser un contenant au choix sur la fenêtre pouvant contenir un menu (si le choix ne convient pas*: le supprimer et recommencer) .Je choisis «*boite*» («*Box*») dans «*Conteneur*» («*containers*») car la hauteur et la largeur s'adaptent automatiquement. Si j'ai besoin d'un autre conteneur pour placer mes futurs items, je les mettrai dans une case de la boite qui ne peut avoir que deux cases*: celle du menu et celle qui contient le conteneur que vous souhaitez avoir.
    3) Je place le menu dans la boite du haut*: «*Barre de menu*» dans «*Conteneur*». Vous pouvez la mettre en bas si vous préférez, voir même à gauche ou à droite si vous modifiez la boite Général->Orientation->Horizontal.
    4) Tester le système de fenêtres
    a) Le programme C qui correspond*:
    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
    #include <stdio.h> 
    #include <stdlib.h> 
    #include <glib.h> 
    #include <gtk/gtk.h> 
     
    struct widgets 
    { 
    	GtkWidget *window; 
    }; 
     
    void cb_quit(void); 
     
    static void get_widgets(struct widgets *widgets, GtkBuilder *builder); 
     
    int main(int argc, char **argv) 
    { 
    	GtkBuilder *builder; 
    	GError *error = NULL; 
    	struct widgets *widgets; 
     
    	gtk_init(&argc, &argv); 
     
    	builder = gtk_builder_new(); 
    	if (!gtk_builder_add_from_file(builder, "test_menu1.glade", &error)) 
    	{ 
    		g_warning("%s", error->message); 
    		exit(EXIT_FAILURE); 
    	} 
     
    	widgets = g_slice_new(struct widgets); 
    	get_widgets(widgets, builder); 
    	gtk_builder_connect_signals(builder, widgets); 
    	g_object_unref(G_OBJECT(builder)); 
     
    	g_signal_connect (widgets->window, "destroy", G_CALLBACK (cb_quit), NULL); 
            gtk_widget_show(widgets->window); 
    	gtk_main(); 
     
    	g_slice_free(struct widgets, widgets); 
     
    	exit(EXIT_SUCCESS); 
    } 
     
    void cb_quit(void) 
    { 
    	gtk_main_quit(); 
    } 
     
    static void get_widgets(struct widgets *widgets, GtkBuilder *builder) 
    { 
    	widgets->window = GTK_WIDGET(gtk_builder_get_object(builder,"window1")); 
    }
    Le makefile*:
    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
    CC=gcc 
     
     CFLAGS= -Wshadow  -Winit-self  -Wredundant-decls  -Wcast-align  -Wundef  -Wfloat-equal  -Winline  -Wunreachable-code  -Wmissing-declarations  -Wmissing-include-dirs  -Wswitch-enum  -Wswitch-default  -Wmain  -Wall  `pkg-config gtk+-3.0 –cflags` -export-dynamic
     
      LDFLAGS=`pkg-config gtk+-3.0 –libs` -export-dynamic 
     
       EXEC=test 
       SRC= $(wildcard *.c) 
    OBJ= $(SRC:.c=.o) 
     
    all: $(EXEC) 
     
    $(EXEC) : $(OBJ) 
    		$(CC) -o $@ $^ $(LDFLAGS) 
     
     
    %.o: %.c 
    		$(CC) -o $@ -c $< $(CFLAGS) 
     
    clean: 
    		rm *.o 
     
    mrproper: clean 
    		rm $(EXEC)
    La compilation*:
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    make

    L'exécution*:
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    ./test

    5) En l'état ça marche, mais quand je ferme la fenêtre, ça ne me rend pas la main dans la ligne de commande.
    6) Connecter les signaux
    C'est pour cela que l'option -export-dynamic est indispensable lors de la compilation. Sinon, les signaux du fichier glade n'arrivent pas à se connecter.
    a) fermer gtk après la fermeture de la fenêtre
    Il faut sélectionner la fenêtre d'origine et l'onglet Signaux->GtkWidjet->destroy. Dans gestionnaire, j'ai mis le nom de la fonction qui ferme gtk*: cb_quit .
    b) Tester un item du menu
    Je choisis le premier item du premier menu. Voici la liste des fenêtres à ouvrir*: windows1->box1->menuitem1->menu1>imagemenuitem1 . Je vais dans l'onglet signaux->activate et j'indique la fonction «*affiche*» dans le gestionnaire. Je la rajoute dans mon main*:
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    void affiche(GtkWidget *p_widget, gpointer param) 
    { 
     printf("1\n"); 
     
     (void) p_widget; 
     (void) param; 
    }

    Dès que j'active le premier item du menu, j'ai un «*1*» qui s'affiche dans la ligne de commande.
    Comprendre.
    7) Lire l'arborescence du menu et des fenêtres.
    Une petite fonction à améliorer*:
    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
    void arboscence(GtkWidget * window,unsigned short niveau) 
    { 
     GList * G_List; 
     unsigned short i; 
     guint nb_s,f; 
     char espace[1024]; 
     
     G_List= gtk_container_get_children(window); 
     while (G_List) 
     { 
            for (i=0;i<niveau;i++) espace[i]=' '; 
            espace [i]=0; 
    	printf("\n%s%s\n",espace,gtk_widget_get_name(G_List->data)); 
                //if ( !GTK_IS_ACCEL_LABEL(G_List->data) && !GTK_IS_MENU_ITEM(G_List->data)  && !GTK_IS_MENU_BAR(G_List->data)   && !GTK_IS_BOX(G_List->data)  ) 
    	    {  /* trouver la liste des propriétés d'un item */ 
    		 GParamSpec ** l_spec=g_object_class_list_properties(G_OBJECT_GET_CLASS(G_List->data),&nb_s); 
    		 for (f=0;f<nb_s;f++)           /* afficher la liste des propriétés */ 
    		 { 
    		     printf("%s| %s \n",espace,l_spec[f]->name); 
    		 } 
    		 printf("%s|____________\n",espace); 
    	    } 
            if ( GTK_IS_CONTAINER(G_List->data) ) 
    		arboscence(G_List->data,niveau+1); 
    	G_List=G_List->next; 
     }
    }

    appelée comme ça*:
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    printf("%s\n",gtk_widget_get_name(widgets->window)); 
    arboscence(widgets->window,1);

    8) Modifier le menu avec glade
    Dans la fenêtre où est affichée la hiérarchie des objets gtk, nous allons éditer les différents éléments du menu.
    Sur la barre de menu, ou tout élément de ce menu*: clic droit sur Menubar->Edit, onglet Hiérarchie, nous ouvrons la boite de dialogue pour travailler le menu. Un clic droit sur un élément du menu ouvre une boite de dialogue

    Ajout de boutons radio dans un menuitem
    faire un clic droit sur l'entrée du menu et choisir «*ajouter un élément fils radio*» pour entrer un item radio de plus dans le menu ou sur un item du menu «*ajouter élément radio*» pour ajouter un item près l'item courant dans le menu. Les boutons radios doivent être regroupés en famille qui ne doit avoir qu'un et qu'un seul élément sélectionné. Pour ceci, il faut sélectionner un bouton radio, dans l'onglet hiérarchie, à la propriété groupe cliquer sur le bouton de droite*: tous les boutons radios apparaissent avec une cache à cocher à gauche (sauf celui sur lequel on travaille), activer la cache d'un bouton qui est dans son groupe et valider.
    Vous pouvez aller dans la fenêtre principale de glade pour tester le groupe de bouton. Attention, il se peut qu'avant la création du groupe vous ayez sélectionné plusieurs boutons radio du groupe*: ils seront encore sélectionnés, commencez à réduire à un le nombre de boutons radios activés en cliquant sur les boutons sélectionnés.

    Menu de Fichiers récents
    Il faut rajouter un fils à un item Élément. Si cet élément ne peut pas avoir de fils, vous aurez alors une fenêtre qui s'ouvrira pour vous prévenir. Ce menu peut être mis par exemple sur un élément image ou un élément normal.
    On peut ensuite effectuer un tri sur les fichiers récents*: par défaut il n'y en a pas. Il faut sélectionner l'entrée Menu de fichiers récents (recentchoosemenu) dans la fenêtre «*inspecteur*» et ensuite dans la fenêtre «*propriétés*» choisir un filtre. S'il n'y en a pas ou si vous en voulez un nouveau cliquez sur [nouveau]. Affectez le bon filtre à votre menu.
    Après, il faut configurer le filtre. Dans la fenêtre «*inspecteur*», le filtre est apparu en bas*: cliquez dessus et confectionnez votre filtre. Le type MIME indiquera les type que vous souhaiter voir apparaître «*text/plain*» ou «*image/**» par exemple. L'entrée Motifs fera un filtre sur vos fichiers comme «**.add*» ou «**.pers*». Attention, vous afficherez les fichiers validant au moins une des conditions.

    Pour les autres éléments la manipulation est la même, mais un peu plus simple*: il n'y a pas à créer de groupe. La différence entre un «*élément image*» («*imagemenuitem*») et un «*élément normal*» («*menuitem*») est qu'on peut attribuer une image au premier un dessin qui sera soit une image prédéfinie («*élément de la collection*») ou une image personnelle («*Étiquette et image personnalisées*»).
    Quoi qu'il en soit, on peut modifier après coup le type d'entrée avec l'entrée type juste en dessous du nom.
    9) Le fichier xml généré.
    C'est un fichier xml assez facilement compréhensible et modifiable.

    10) Rajouter/modifier la configuration avec le programme.
    A ) Rajouter élément dans arborescence hors menu
    Si vous avez utilisé glade juste pour faire votre menu, vous pouvez ensuite facilement construire votre fenêtre.
    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
    G_List= gtk_container_get_children(GTK_CONTAINER(widgets->window)); 
    while ( !GTK_IS_BOX(G_List->data) ) 
    { 
      G_List=G_List->next; 
    } /* le fichier est conçu pour que le menu soit dans un vbox, en dessous, on met ce qu'on veut */ 
    if ( GTK_IS_BOX(G_List->data) ) 
    { /* ici, je mets un bouton */ 
      bouton = gtk_button_new_with_label ("test"); 
      gtk_box_pack_start (GTK_BOX (G_List->data), bouton, TRUE, TRUE, 0); 
      gtk_widget_show(bouton); 
    } 
    else 
    { 
      printf("problème\n"); 
    }
    Modérateur Mageia/Mandriva Linux
    Amicalement VOOotre
    Troumad Alias Bernard SIAUD à découvrir sur http://troumad.org
    Mes tutoriels : xrandr, algorigramme et C, xml et gtk...

  2. #2
    Rédacteur/Modérateur

    Ping ?

    Je reprends un peu ce travail car j'ai un peu de temps... Mais, Est-ce que ça vaut le coup ?
    Modérateur Mageia/Mandriva Linux
    Amicalement VOOotre
    Troumad Alias Bernard SIAUD à découvrir sur http://troumad.org
    Mes tutoriels : xrandr, algorigramme et C, xml et gtk...

  3. #3
    Rédacteur/Modérateur

    Pong ?
    Toujours aucun intérêt ? je continue le travail pour moi ? Ou pour tous ?

    Bon, je viens de rajouter quelques lignes et j'en ai d'autres à rajouter suite à un petit test.
    Modérateur Mageia/Mandriva Linux
    Amicalement VOOotre
    Troumad Alias Bernard SIAUD à découvrir sur http://troumad.org
    Mes tutoriels : xrandr, algorigramme et C, xml et gtk...

  4. #4
    Rédacteur/Modérateur

    Je crois que je laisse tomber...

    En effet,
    1) Personne ne semble intéressé
    2) Je ne trouve aucune doc (français ou anglais), ni aucun exemple sur ce que je cherche à faire : modifier de façon dynamique un menu généré par glade.
    Modérateur Mageia/Mandriva Linux
    Amicalement VOOotre
    Troumad Alias Bernard SIAUD à découvrir sur http://troumad.org
    Mes tutoriels : xrandr, algorigramme et C, xml et gtk...

  5. #5
    Expert confirmé
    Houla ! La déprime te guète

    Je viens à ton secours. Pourrais-tu mettre le code source xml du fichier glade de ton application pour que je puisse tester de mon côté ?
    Utilisation de Glade avec Gtk+ - N'oubliez pas de consulter les FAQ Gtk et les cours et tutoriels Gtk

  6. #6
    Rédacteur/Modérateur

    J'ai laisser tomber cette partie de mon programme, car je me sers surtout de l'autre...
    Ce qui m'intéresse, c'est d'avoir le principale, ou le squelette du menu en XML, puis après de pouvoir modifier/compléter des sous menus une fois que le programme est lancé avec ses propres menus venant de glade. Et là, je ne vois pas du tout comment faire. Je ne trouve aucun exemple. Peut-être que ma phobie de l'anglais ne me permet pas de tout saisir dans la doc gtk, mais je n'ai rien vu me permettant d'y arriver.
    Modérateur Mageia/Mandriva Linux
    Amicalement VOOotre
    Troumad Alias Bernard SIAUD à découvrir sur http://troumad.org
    Mes tutoriels : xrandr, algorigramme et C, xml et gtk...

  7. #7
    Expert confirmé
    Je ne sais pas si c'est bien ce que tu cherches à faire mais voici un petit exemple.

    J'ai créé une fenêtre principale avec une GtkBox et un GtkMenuBar dedans. Rien que du classique jusque là. J'ai ensuite créé une deuxième fenêtre principale dans le même fichier Glade qui contient un autre GtkMenuBar. Cet autre menu est le menu que tu désires construire avec Glade mais qui n'est pas affiché par défaut. Il sera inséré en toute ou partie dans le principal qui lui est affiché par défaut.

    Pour l'exemple le menu affiché dispose d'une entrée "Affichage" qui ne contient rien au départ. L'entrée "Enregistrer" du menu "Fichier" est affectée à un callback cb_save();. Dans ce callback je récupère le menu "Fichier" de l'autre GtkMenuBar qui lui n'est pas affiché. Je l'insère ensuite dans l'Entrée "Affichage".

    Ainsi on peut avoir des menus dynamiques sans être obligé de les constuire dans le source. Je ne sais pas si c'est bien ca que tu cherches à faire mais bon, j'aurai essayé .

    Source du fichier xml ("test_menu1.glade") :
    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
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    <?xml version="1.0" encoding="UTF-8"?>
    <!-- Generated with glade 3.18.3 -->
    <interface>
      <requires lib="gtk+" version="3.12"/>
      <object class="GtkWindow" id="window">
        <property name="can_focus">False</property>
        <signal name="delete-event" handler="cb_quit" swapped="no"/>
        <child>
          <object class="GtkBox" id="box1">
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="orientation">vertical</property>
            <child>
              <object class="GtkMenuBar" id="menubar">
                <property name="visible">True</property>
                <property name="can_focus">False</property>
                <child>
                  <object class="GtkMenuItem" id="menufichier">
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
                    <property name="label" translatable="yes">_Fichier</property>
                    <property name="use_underline">True</property>
                    <child type="submenu">
                      <object class="GtkMenu" id="menu1">
                        <property name="visible">True</property>
                        <property name="can_focus">False</property>
                        <child>
                          <object class="GtkImageMenuItem" id="imagemenuitem1">
                            <property name="label">gtk-new</property>
                            <property name="visible">True</property>
                            <property name="can_focus">False</property>
                            <property name="use_underline">True</property>
                            <property name="use_stock">True</property>
                          </object>
                        </child>
                        <child>
                          <object class="GtkImageMenuItem" id="imagemenuitem2">
                            <property name="label">gtk-open</property>
                            <property name="visible">True</property>
                            <property name="can_focus">False</property>
                            <property name="use_underline">True</property>
                            <property name="use_stock">True</property>
                          </object>
                        </child>
                        <child>
                          <object class="GtkImageMenuItem" id="itemenregistrer">
                            <property name="label">gtk-save</property>
                            <property name="visible">True</property>
                            <property name="can_focus">False</property>
                            <property name="use_underline">True</property>
                            <property name="use_stock">True</property>
                            <signal name="activate" handler="cb_save" swapped="no"/>
                          </object>
                        </child>
                        <child>
                          <object class="GtkImageMenuItem" id="imagemenuitem4">
                            <property name="label">gtk-save-as</property>
                            <property name="visible">True</property>
                            <property name="can_focus">False</property>
                            <property name="use_underline">True</property>
                            <property name="use_stock">True</property>
                          </object>
                        </child>
                        <child>
                          <object class="GtkSeparatorMenuItem" id="separatormenuitem1">
                            <property name="visible">True</property>
                            <property name="can_focus">False</property>
                          </object>
                        </child>
                        <child>
                          <object class="GtkImageMenuItem" id="imagemenuitem5">
                            <property name="label">gtk-quit</property>
                            <property name="visible">True</property>
                            <property name="can_focus">False</property>
                            <property name="use_underline">True</property>
                            <property name="use_stock">True</property>
                          </object>
                        </child>
                      </object>
                    </child>
                  </object>
                </child>
                <child>
                  <object class="GtkMenuItem" id="menuedition">
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
                    <property name="label" translatable="yes">É_dition</property>
                    <property name="use_underline">True</property>
                    <child type="submenu">
                      <object class="GtkMenu" id="menu2">
                        <property name="visible">True</property>
                        <property name="can_focus">False</property>
                        <child>
                          <object class="GtkImageMenuItem" id="imagemenuitem6">
                            <property name="label">gtk-cut</property>
                            <property name="visible">True</property>
                            <property name="can_focus">False</property>
                            <property name="use_underline">True</property>
                            <property name="use_stock">True</property>
                          </object>
                        </child>
                        <child>
                          <object class="GtkImageMenuItem" id="imagemenuitem7">
                            <property name="label">gtk-copy</property>
                            <property name="visible">True</property>
                            <property name="can_focus">False</property>
                            <property name="use_underline">True</property>
                            <property name="use_stock">True</property>
                          </object>
                        </child>
                        <child>
                          <object class="GtkImageMenuItem" id="imagemenuitem8">
                            <property name="label">gtk-paste</property>
                            <property name="visible">True</property>
                            <property name="can_focus">False</property>
                            <property name="use_underline">True</property>
                            <property name="use_stock">True</property>
                          </object>
                        </child>
                        <child>
                          <object class="GtkImageMenuItem" id="imagemenuitem9">
                            <property name="label">gtk-delete</property>
                            <property name="visible">True</property>
                            <property name="can_focus">False</property>
                            <property name="use_underline">True</property>
                            <property name="use_stock">True</property>
                          </object>
                        </child>
                      </object>
                    </child>
                  </object>
                </child>
                <child>
                  <object class="GtkMenuItem" id="menuaffichage">
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
                    <property name="label" translatable="yes">_Affichage</property>
                    <property name="use_underline">True</property>
                  </object>
                </child>
                <child>
                  <object class="GtkMenuItem" id="menuaide">
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
                    <property name="label" translatable="yes">Aid_e</property>
                    <property name="use_underline">True</property>
                    <child type="submenu">
                      <object class="GtkMenu" id="menu3">
                        <property name="visible">True</property>
                        <property name="can_focus">False</property>
                        <child>
                          <object class="GtkImageMenuItem" id="imagemenuitem10">
                            <property name="label">gtk-about</property>
                            <property name="visible">True</property>
                            <property name="can_focus">False</property>
                            <property name="use_underline">True</property>
                            <property name="use_stock">True</property>
                          </object>
                        </child>
                      </object>
                    </child>
                  </object>
                </child>
              </object>
              <packing>
                <property name="expand">False</property>
                <property name="fill">True</property>
                <property name="position">0</property>
              </packing>
            </child>
            <child>
              <placeholder/>
            </child>
            <child>
              <placeholder/>
            </child>
          </object>
        </child>
      </object>
      <object class="GtkWindow" id="window1">
        <property name="can_focus">False</property>
        <child>
          <object class="GtkMenuBar" id="menubar1">
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <child>
              <object class="GtkMenuItem" id="sousmenu">
                <property name="visible">True</property>
                <property name="can_focus">False</property>
                <property name="label" translatable="yes">_Fichier</property>
                <property name="use_underline">True</property>
                <child type="submenu">
                  <object class="GtkMenu" id="menu4">
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
                    <child>
                      <object class="GtkImageMenuItem" id="imagemenuitem3">
                        <property name="label">gtk-new</property>
                        <property name="visible">True</property>
                        <property name="can_focus">False</property>
                        <property name="use_underline">True</property>
                        <property name="use_stock">True</property>
                      </object>
                    </child>
                    <child>
                      <object class="GtkImageMenuItem" id="imagemenuitem11">
                        <property name="label">gtk-open</property>
                        <property name="visible">True</property>
                        <property name="can_focus">False</property>
                        <property name="use_underline">True</property>
                        <property name="use_stock">True</property>
                      </object>
                    </child>
                    <child>
                      <object class="GtkImageMenuItem" id="imagemenuitem12">
                        <property name="label">gtk-save</property>
                        <property name="visible">True</property>
                        <property name="can_focus">False</property>
                        <property name="use_underline">True</property>
                        <property name="use_stock">True</property>
                      </object>
                    </child>
                    <child>
                      <object class="GtkImageMenuItem" id="imagemenuitem13">
                        <property name="label">gtk-save-as</property>
                        <property name="visible">True</property>
                        <property name="can_focus">False</property>
                        <property name="use_underline">True</property>
                        <property name="use_stock">True</property>
                      </object>
                    </child>
                    <child>
                      <object class="GtkSeparatorMenuItem" id="separatormenuitem2">
                        <property name="visible">True</property>
                        <property name="can_focus">False</property>
                      </object>
                    </child>
                    <child>
                      <object class="GtkImageMenuItem" id="imagemenuitem14">
                        <property name="label">gtk-quit</property>
                        <property name="visible">True</property>
                        <property name="can_focus">False</property>
                        <property name="use_underline">True</property>
                        <property name="use_stock">True</property>
                      </object>
                    </child>
                  </object>
                </child>
              </object>
            </child>
            <child>
              <object class="GtkMenuItem" id="menuitem2">
                <property name="visible">True</property>
                <property name="can_focus">False</property>
                <property name="label" translatable="yes">É_dition</property>
                <property name="use_underline">True</property>
                <child type="submenu">
                  <object class="GtkMenu" id="menu5">
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
                    <child>
                      <object class="GtkImageMenuItem" id="imagemenuitem15">
                        <property name="label">gtk-cut</property>
                        <property name="visible">True</property>
                        <property name="can_focus">False</property>
                        <property name="use_underline">True</property>
                        <property name="use_stock">True</property>
                      </object>
                    </child>
                    <child>
                      <object class="GtkImageMenuItem" id="imagemenuitem16">
                        <property name="label">gtk-copy</property>
                        <property name="visible">True</property>
                        <property name="can_focus">False</property>
                        <property name="use_underline">True</property>
                        <property name="use_stock">True</property>
                      </object>
                    </child>
                    <child>
                      <object class="GtkImageMenuItem" id="imagemenuitem17">
                        <property name="label">gtk-paste</property>
                        <property name="visible">True</property>
                        <property name="can_focus">False</property>
                        <property name="use_underline">True</property>
                        <property name="use_stock">True</property>
                      </object>
                    </child>
                    <child>
                      <object class="GtkImageMenuItem" id="imagemenuitem18">
                        <property name="label">gtk-delete</property>
                        <property name="visible">True</property>
                        <property name="can_focus">False</property>
                        <property name="use_underline">True</property>
                        <property name="use_stock">True</property>
                      </object>
                    </child>
                  </object>
                </child>
              </object>
            </child>
            <child>
              <object class="GtkMenuItem" id="menuitem3">
                <property name="visible">True</property>
                <property name="can_focus">False</property>
                <property name="label" translatable="yes">_Affichage</property>
                <property name="use_underline">True</property>
              </object>
            </child>
            <child>
              <object class="GtkMenuItem" id="menuitem4">
                <property name="visible">True</property>
                <property name="can_focus">False</property>
                <property name="label" translatable="yes">Aid_e</property>
                <property name="use_underline">True</property>
                <child type="submenu">
                  <object class="GtkMenu" id="menu6">
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
                    <child>
                      <object class="GtkImageMenuItem" id="imagemenuitem19">
                        <property name="label">gtk-about</property>
                        <property name="visible">True</property>
                        <property name="can_focus">False</property>
                        <property name="use_underline">True</property>
                        <property name="use_stock">True</property>
                      </object>
                    </child>
                  </object>
                </child>
              </object>
            </child>
          </object>
        </child>
      </object>
    </interface>


    Source du main.c. Je l'ai un peu revisité :
    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
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    #include <stdio.h> 
    #include <stdlib.h> 
    #include <glib.h> 
    #include <gtk/gtk.h> 
     
    struct widgets 
    { 
      GtkWidget *window;
      GtkBuilder *builder;
    }; 
     
    void get_widgets(struct widgets *widgets); 
    void cb_save (GtkMenuItem *menuitem, struct widgets *widgets);
    gboolean cb_quit (GtkWidget *widget, GdkEvent  *event, struct widgets *widgets);
     
    int main(int argc, char **argv) 
    { 
      GError *error = NULL; 
      struct widgets widgets; 
     
      gtk_init(&argc, &argv); 
     
      widgets.builder = gtk_builder_new(); 
      if (!gtk_builder_add_from_file(widgets.builder, "test_menu1.glade", &error)) 
        { 
          g_warning("%s", error->message);
          g_error_free(error);
          exit(EXIT_FAILURE); 
        } 
     
      get_widgets(&widgets); 
      gtk_builder_connect_signals(widgets.builder, &widgets); 
     
      gtk_widget_show(widgets.window); 
      gtk_main(); 
     
      g_object_unref(G_OBJECT(widgets.builder));
     
      exit(EXIT_SUCCESS); 
    }
     
    gboolean
    cb_quit (GtkWidget *widget, GdkEvent  *event, struct widgets *widgets)
    { 
      gtk_main_quit();
     
      return TRUE;
    } 
     
    void
    get_widgets(struct widgets *widgets) 
    { 
      widgets->window = GTK_WIDGET(gtk_builder_get_object(widgets->builder,"window")); 
    }
     
    void
    cb_save (GtkMenuItem *menuitem, struct widgets *widgets)
    {
       // Pour l'exemple, le menu "Enregistrer" activé va ajouter un menu à l'entrée Affichage qui ne contient rien pour l'instant.
      // Ce nouveau menu est construit dans le fichier glade.
     
      // On récupère l'entrée du menu Affichage
      GtkMenuItem *menuaffichage = GTK_MENU_ITEM (gtk_builder_get_object(widgets->builder,"menuaffichage"));
     
      // Récupération du menu à insérer depuis le fichier Glade
      GtkWidget *menu = GTK_WIDGET (gtk_builder_get_object(widgets->builder,"menu4"));
     
      // Il est nécessaire de détacher le menu récupéré du widget parent dans le fichier Glade.
      // Ceci évite un warning en console
      gtk_menu_detach (GTK_MENU(menu));
     
      // Insértion du menu
      gtk_menu_item_set_submenu (menuaffichage, menu);
    }
    Utilisation de Glade avec Gtk+ - N'oubliez pas de consulter les FAQ Gtk et les cours et tutoriels Gtk

  8. #8
    Rédacteur/Modérateur

    OK ! Merci.

    je vais regarder ça et te dire ce que j'en pense. J'aurais peut-être un peu de temps Jeudi ou Vendredi.
    Modérateur Mageia/Mandriva Linux
    Amicalement VOOotre
    Troumad Alias Bernard SIAUD à découvrir sur http://troumad.org
    Mes tutoriels : xrandr, algorigramme et C, xml et gtk...

  9. #9
    Rédacteur/Modérateur

    Je viens de regarder.

    La surprise, c'est que si je compile avec code::blocks, lors de l'exécution, le programme ne trouve pas les fonctions :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    (test_glade:4038): Gtk-WARNING **: Could not find signal handler 'cb_quit'.  Did you compile with -rdynamic?
     
    (test_glade:4038): Gtk-WARNING **: Could not find signal handler 'cb_save'.  Did you compile with -rdynamic?

    Alors que je je compile avec mon makefile, c'est bon.
    Je rajoute donc l'option -rdynamic dans le menu "project build optios ->Linker setting-> Other linker options" de code blocks. Et ça passe pour code blocks.
    La surprise est donc résolue.

    Après, je regarde le source pour comprendre ce qui se passe.

    1) Dans ton fichier glade, tu définis 2 fenêtres.
    2) Avec ta fonction get_widgets tu sélectionnes la première fenêtre.
    3) La fonction cb_save récupère le sous_menu menu4 de ton fichier glade pour la mettre dans l'entrée "menuaffichage"


    Ceci ne correspond pas tout à fait à ce que je cherchais, mais ça va peut-être me mettre sur la voie.
    Je cherche à modifier un sous-menu pour y rajouter des entrées que ne sont pas dans un fichier glade. Ces entrées seront modifiées en fonctions de fichiers se trouvant dans certains répertoires.
    Modérateur Mageia/Mandriva Linux
    Amicalement VOOotre
    Troumad Alias Bernard SIAUD à découvrir sur http://troumad.org
    Mes tutoriels : xrandr, algorigramme et C, xml et gtk...

  10. #10
    Expert confirmé
    Le principe est le même? J'ai mis à côté mais la piste est là même.

    Surtout ne détruis ton GtkBuilder qu'en fin de programme (ou d'exécution définitive de l'interface ciblée). Tu peux en effet récupérer tout widget (GtkMenu, GtkMenuItem...) et ensuite, via le code source y ajouter de nouveaux GtkMenu et GtkMenuItem.

    J'utilise ta structure widget pour propager dans tous les callbacks le GtkBuilder. À partir de là tu le manipules selon tes besoins. Mais ca, tu connais déjà . Propager dans ta structure le pointeur sur la fenêtre principale n'a pas d'intérêt ici puisque tu peux l'avoir à tout instant par le GtkBuilder. Tu peux donc, selon les besoins, te passer de la structure et propager directement le GtkBuilder.

    Si tu conserves une structure dans l'idée de propager d'autres variables/pointeurs externes au GtkBuilder, tu peux faire comme je l'ai fait dans ton main. Je n'alloue pas dans le tas. Je déclare une variable et propage simplement son adresse. Cette variable sera viable tant que l'on ne sort pas du main();, donc pour toute la durée de vie de l'application. Un malloc(); de moins c'est une source d'emm&é"$^ de moins.
    Utilisation de Glade avec Gtk+ - N'oubliez pas de consulter les FAQ Gtk et les cours et tutoriels Gtk

  11. #11
    Rédacteur/Modérateur

    J'essaie de créer un menu sur une entrée quelconque d'un menu.

    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
    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
    void
    cb_save (GtkMenuItem *menuitem, struct widgets *widgets)
    {
       GtkMenuItem *menuaffichage;
       GtkWidget *pMenu ;
       GtkWidget *e_menu ;
       static unsigned short i=0;
       GList * gl;
       char nom[32];
       unsigned short j;
     
      menuaffichage = GTK_MENU_ITEM (gtk_builder_get_object(widgets->builder,"Classe"));
      if (menuaffichage==NULL)
      {
          printf("Entrée classe non trouvée\n");
      }
      else
      {
          printf("Entrée classe trouvée\n");
          pMenu=gtk_menu_item_get_submenu(GTK_MENU_ITEM(menuaffichage));                                      /* on trouve le sous-menu                             */
          if (pMenu==NULL)
          {
              printf("Sans sous-menu\n");
              pMenu=gtk_menu_new ();
          }
          else
          {
              gl=gtk_container_get_children(GTK_CONTAINER(pMenu));
              for (j=0; gl != NULL; gl= g_list_next(gl),j++)
              {
                  printf("  %s\n",gtk_menu_item_get_label(GTK_MENU_ITEM(gl->data)));
              }
              printf("Avec sous-menu à %hu entrée(s)\n",j);
          }
          //e_menu=gtk_menu_item_new_with_label("Entrée");
          sprintf(nom,"Nom %hu",i);
    printf("%s\n",nom);
          //e_menu = gtk_radio_menu_item_new_with_mnemonic(NULL,nom);
          e_menu =gtk_menu_item_new_with_mnemonic (nom);
          sprintf(nom,"Entrée %hu",i);
    printf("%s\n",nom);
          gtk_menu_item_set_label(GTK_MENU_ITEM(e_menu),nom);
          gtk_menu_shell_insert(GTK_MENU_SHELL(pMenu),e_menu,i);
          if (e_menu==NULL) printf("Erreur !");
          gtk_menu_item_set_submenu (menuaffichage, pMenu);
          i++;
      }
     
    }


    Le problème, c'est qu'il n'y a rien qui apparait comme menu. Le sous menu se crée mais vide Par contre, avec tous les "printf" que j'ai mis, je vois que le programme fait bien ce que je souhaite :
    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
    Entrée classe trouvée
    Sans sous-menu
    Nom 0
    Entrée 0
    Entrée classe trouvée
      Entrée 0
    Avec sous-menu à 1 entrée(s)
    Nom 1
    Entrée 1
    Entrée classe trouvée
      Entrée 0
      Entrée 1
    Avec sous-menu à 2 entrée(s)
    Nom 2
    Entrée 2


    Je ne vois pas où est le problème.


    je continue le reste en attendant d'avoir une idée.
    J'ai un groupe de 6 paquets de boutons radios numéroté de 1 à 6 les 6 fois. Je ne souhaite mettre qu'une seule fonction fonction callback pour analyser la modification qui a été faite. Le fonction "gtk_menu_item_get_label(menuitem)" me donne le numéro de 1 à 6 du bouton qui a été activé. Mais, je ne vois pas comment savoir duquel des 6 groupes il s'agit.
    J'ai rajouté à la main une propriété "name" au bouton dans le fichier glade :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    <property name="name">F1</property>

    Je peux récupérer ce nom avec :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    g_object_get(menuitem,"name",     &nom,NULL);

    Mais, est-ce bien permis ? Y-a-t-il mieux ?
    Modérateur Mageia/Mandriva Linux
    Amicalement VOOotre
    Troumad Alias Bernard SIAUD à découvrir sur http://troumad.org
    Mes tutoriels : xrandr, algorigramme et C, xml et gtk...

  12. #12
    Rédacteur/Modérateur

    J'avais oublié de mettre à la fin le :
    Modérateur Mageia/Mandriva Linux
    Amicalement VOOotre
    Troumad Alias Bernard SIAUD à découvrir sur http://troumad.org
    Mes tutoriels : xrandr, algorigramme et C, xml et gtk...

  13. #13
    Rédacteur/Modérateur

    Citation Envoyé par troumad Voir le message
    L'entrée Motifs fera un filtre sur vos fichiers comme «**.add*» ou «**.pers*». Attention, vous afficherez les fichiers validant au moins une des conditions.
    Pour compléter mon aide, que faire si je souhaite que le système n'affiche que les grp ET les pers ?

    Édit : Je me réponds à moi-même : il faut remplir deux lignes dans motifs. Il me semblait que j'avais essayé, mais que ça ne marchait pas... Cette fois, j'y suis arrivé !
    Modérateur Mageia/Mandriva Linux
    Amicalement VOOotre
    Troumad Alias Bernard SIAUD à découvrir sur http://troumad.org
    Mes tutoriels : xrandr, algorigramme et C, xml et gtk...

  14. #14
    Membre confirmé
    Salutations,

    De mon petit avis, j’aurais apprécié un article avec vidéo tutoriel montrant comment faire un menu polymorphe(qui change selon le contexte) avec Glade. Donc ma petite personne est intéressé par un tel tutoriel.

    J'ai réussis à trouvé des tutoriels pour le faire programmatiquement -mais là c'est casse tête-; ou avec GtkUIMAnager mais pas avec Glade.
    Et aussi une vidéo qui montre comment créer un mais c'est statique.

    Le scénario classique, une application charge des plugins qui enrichissent l'interface graphique donc le menu.

    Pour ce qui est des menu item dynamique comme "Fichier récente" là ça sort de mon cadre de compétences.

    Bien à vous,

  15. #15
    Rédacteur/Modérateur

    Ce ne sera pas moi qui ferai une telle vidéo car je ne comprends pas l'intérêt de ces vidéo où j'ai l'impression de perdre mon temps devant un film lent alors qu'un écrit se parcourt plus rapidement et qu'après, on peut revenir sur les points importants plu facilement*. Mais, si tu en fais un, je pourrais le regarder pour te donner mon avis.

    * : c'est peut-être une histoire de génération et je suis peut-être vieux-jeu...
    Modérateur Mageia/Mandriva Linux
    Amicalement VOOotre
    Troumad Alias Bernard SIAUD à découvrir sur http://troumad.org
    Mes tutoriels : xrandr, algorigramme et C, xml et gtk...

  16. #16
    Membre confirmé
    J'disais que j’étais intéressé et par quoi.

    Mais bon, pour ne pas contre dire l'adage: "Qui s'y frotte s'y colle" j'vais essayer de le faire marché déjà, et si j'y arrive j'écrirai un tutoriel avec une vidéo, mais bon moi c'est vite fais, vous attendez pas a 4 page de texte et une vidéo de 1 heures.

    c'est peut-être une histoire de génération et je suis peut-être vieux-jeu...
    Bha ché pas, t'as quel âge ? moi j'trouve que les vidéo c'est plus simple pour tout ce qui est graphique : Une petite vidéo vaux mieux qu'un grand tutoriel ... Mais je te rejoins en disant que pour la programmation , ce genre de c'est l’horreur