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 :

Boutons inopérants (et troisième mot pour que le forum soit content)


Sujet :

GTK+ avec C & C++

  1. #1
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 726
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 726
    Points : 15 126
    Points
    15 126
    Par défaut Boutons inopérants (et troisième mot pour que le forum soit content)
    Bonjour,

    je découvre gtk alors je suis archi newbie dans le domaine, et je suis parti d'un exemple trouvé dans un bouquin énorme (presque 900 pages).

    Pour eux qui voudraient tester, je me suis tapé la transformation de la partie qui m'intéresse et qui se trouve à la page 793 (826 du pdf) et que je recopie ci-dessous avec deux petites modifications lignes 44 et 158 de mon fichier codevdoc.c.

    Ça compile bien avec ce Makefile dans une machine Linux :
    Code Makefile : 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
    # Makefile inspiré de celui trouvé dans hdparm et par
    # https://www.developpez.net/forums/d2126933/c-cpp/c/debuter/probleme-d-include-fichier-non-trouve-qu-bien-present/#post11819054
     
    ifndef C99
            C99 = gcc
    endif
     
    PKGCONFIG = $(shell which pkg-config)
     
    CFLAGS = $(shell $(PKGCONFIG) --cflags gtk+-2.0) -std=c99
    LDLIBS = $(shell $(PKGCONFIG) --libs gtk+-2.0)
     
    PROG = codevdoc
     
    all: ${PROG}
     
    clean:
    	rm -f *.o ${PROG}

    Et ce que je constate à l'exécution, c'est que la fenêtre s'affiche, mais vide, et je n'ai pas compris si ce sont les boutons (qui réagissent visuellement aux clics) qui vont générer un affichage ou s'ils modifient un affichage déjà présent.

    Ah, un truc curieux : quand je ferme le prog en cliquant sur la croix, il disparait mais, lancé dans une console, il ne rend pas la main, je dois le killer depuis une autre console pour libérer la première, bizarre bizarre. J'ai rajouté un return 0; juste avant la fin du main (comme on peut le voir ici) mais ça ne change rien à ce comportement zarbi,


    Un ch'tit coup de main sur ce coup-là serait bienvenu et sympatoche, merci d'avance,


    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
    /* p 793-797 vdoc.pub_gtk-programming-in-c.pdf */
     
    # include <stdlib.h>
    # include <stdint.h> /* pour malloc */
     
    # include <gtk-2.0/gtk/gtk.h>
    # include <gtk-2.0/gdk/gdk.h> 
     
    #define RED   1
    #define GREEN 2
    #define BLUE  4
     
    typedef struct piece {
      int x;
      int y;
      guint32 time;
      unsigned char color;
    } Piece;
     
    typedef struct cleardata {
      GtkWidget *w;
      GList **list;
    } ClearData;
     
    static GtkWidget *gRedPmap, *gGreenPmap, *gBluePmap;
    static unsigned char gColor = RED;
     
    static GtkWidget*
    NewPixmap( char *filename, GdkWindow *window, GdkColor *background )
    {
      GtkWidget *wpixmap;
      GdkPixmap *pixmap;
      GdkBitmap *mask;
     
      pixmap = gdk_pixmap_create_from_xpm( window, &mask, background, filename );
      wpixmap = gtk_pixmap_new( pixmap, mask );
     
      return wpixmap;
    }
     
    static void
    SetColor( GtkWidget *widget, gpointer arg )
    {
    //  gColor = (unsigned char) arg;
    // https://stackoverflow.com/questions/21323628/warning-cast-to-from-pointer-from-to-integer-of-different-size
      gColor = (intptr_t) arg;
    }
     
    static void
    ClearDrawing ( GtkWidget *widget, gpointer arg )
    {
      ClearData *p = (ClearData *) arg;
      GList **list = p->list;
      GList *tmp_list;
     
      for (tmp_list = *list; tmp_list; tmp_list = tmp_list->next)
          g_free(tmp_list->data);
     
      g_list_free(*list);
      *list = (GList *) NULL;
     
      gdk_window_clear( p->w->window );
    }
     
    static int
    CompFunc( gconstpointer a, gconstpointer b )
    {
      Piece *piece1, *piece2;
     
      piece1 = (Piece *) a;
      piece2 = (Piece *) b;
     
      if ( piece1->time < piece2->time )
        return FALSE;
      return TRUE;
    }
     
    static gint
    ButtonPress( GtkWidget *widget, GdkEventButton *event, gpointer arg )
    {
      ClearData *p = (ClearData *) arg;
      GList **items = (GList **) p->list;
      GtkPixmap *pixmap;
      Piece *piece;
     
      piece = (Piece *) malloc( sizeof( Piece ) );
      piece->color = gColor;
      piece->x = (gint) event->x;
      piece->y = (gint) event->y;
      piece->time = gdk_event_get_time( (GdkEvent *) event );
      *items = g_list_insert_sorted( *items, piece, CompFunc );
     
      switch ( piece->color ) {
        case RED:
          pixmap = GTK_PIXMAP( gRedPmap );
          break;
        case GREEN:
          pixmap = GTK_PIXMAP( gGreenPmap );
          break ;
        case BLUE:
          pixmap = GTK_PIXMAP( gBluePmap ) ;
          break ;
      }
     
      gdk_draw_pixmap( widget->window, widget->style->black_gc,
      pixmap->pixmap, 0, 0, piece->x, piece->y, -1, -1 );
    }
     
    static gint
    HandleExpose( GtkWidget *widget, GdkEventExpose *event, gpointer arg )
    {
      GList **p = (GList **) arg, *list = (GList *) *p;
      GdkRectangle rect, dest;
      GtkPixmap *pixmap;
      Piece *piece;
      int i;
     
      for ( i = 0; *p != (GList *) NULL; i++, *p = g_list_next( * p ) ) {
        piece = g_list_nth_data( (GList *) list, i );
        rect.x = piece->x;
        rect.y = piece->y;
        rect.width = rect.height = 20;
        if ( gdk_rectangle_intersect (
          &rect, &event->area, &dest ) == TRUE ) {
          switch ( piece->color ) {
            case RED:
              pixmap = GTK_PIXMAP( gRedPmap );
              break;
            case GREEN:
              pixmap = GTK_PIXMAP( gGreenPmap );
              break;
            case BLUE:
              pixmap = GTK_PIXMAP( gBluePmap );
              break;
            default:
              continue;
          }
          gdk_draw_pixmap( widget->window,
            widget->style->black_gc,
            pixmap->pixmap, 0, 0,
            piece->x, piece->y, -1, -1 );
        }
      }
      *p = list;
    }
     
    int main( int argc, char *argv[] )
    {
      GtkWidget *dialog, *button, *drawing, *toolbar;
      GList *items = (GList *) NULL;
      ClearData cd;
     
      gtk_init( &argc, &argv );
      dialog = gtk_dialog_new ();
      gtk_window_position( GTK_WINDOW( dialog ), GTK_WIN_POS_MOUSE );
      gtk_widget_show( dialog );
     
    //  toolbar = gtk_toolbar_new( GTK_ORIENTATION_HORIZONTAL, GTK_TOOLBAR_BOTH );
      toolbar = gtk_toolbar_new();
      gtk_toolbar_set_style(GTK_TOOLBAR(toolbar), GTK_TOOLBAR_BOTH);
     
      gRedPmap = NewPixmap( "red.xpm", dialog->window,
        &dialog->style->bg [GTK_STATE_NORMAL] ),
        gtk_toolbar_append_item( GTK_TOOLBAR(toolbar), "Red ",
        "Draw red square", NULL, gRedPmap,
        (GtkSignalFunc) SetColor, (gpointer) RED );
      gGreenPmap = NewPixmap ( "green.xpm", dialog->window,
        &dialog->style->bg[GTK_STATE_NORMAL] ),
        gtk_toolbar_append_item( GTK_TOOLBAR(toolbar), "Green",
        "Draw green square", NULL, gGreenPmap,
        (GtkSignalFunc) SetColor, (gpointer) GREEN );
      gBluePmap = NewPixmap( "blue.xpm", dialog->window,
        &dialog->style->bg [GTK_STATE_NORMAL] ),
        gtk_toolbar_append_item( GTK_TOOLBAR(toolbar), "Blue",
        "Draw blue square", NULL, gBluePmap,
        (GtkSignalFunc) SetColor, (gpointer) BLUE );
     
      gtk_box_pack_start( GTK_BOX( GTK_DIALOG( dialog )->vbox ), toolbar,
        FALSE, TRUE, 0 );
     
      drawing = gtk_drawing_area_new();
      gtk_drawing_area_size( GTK_DRAWING_AREA( drawing ), 320, 200 );
      gtk_signal_connect( GTK_OBJECT( drawing ), " expose_event " ,
        GTK_SIGNAL_FUNC( HandleExpose ), &items );
      gtk_widget_set_events( drawing,
        GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK);
      cd.w = drawing;
      cd.list = &items;
      gtk_signal_connect( GTK_OBJECT( drawing ), "button_press _event",
        GTK_SIGNAL_FUNC( ButtonPress ), &cd );
     
      gtk_box_pack_start( GTK_BOX( GTK_DIALOG( dialog )->vbox ), drawing,
        TRUE, TRUE, 0 );
     
      button = gtk_button_new_with_label( "Clear" );
      gtk_box_pack_start( GTK_BOX( GTK_DIALOG( dialog )->action_area ),
        button, TRUE, FALSE, 0 );
      gtk_signal_connect( GTK_OBJECT( button ), "clicked",
        GTK_SIGNAL_FUNC( ClearDrawing ), &cd );
     
      gtk_widget_show_all( dialog );
      gtk_main();
      return 0; // ajout moi
    }
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

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

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

    Informations forums :
    Inscription : Février 2008
    Messages : 2 291
    Points : 4 941
    Points
    4 941
    Billets dans le blog
    5
    Par défaut
    Bonjour.

    Première remarque qu'on t'a peut-être déjà faite. Tu es un nouvel utilisateur de Gtk+. Oublie tout de suite Gtk2. Il est totalement obsolète. Gtk en est à la version 4. Comme pour l'instant la documentation de cette version n'est pas très fournie je te propose d'utiliser Gtk3. Le passage de Gtk3 vers Gtk4 sera assez façile par la suite.

    Deuxième remarque sur le code source. Je vais répondre à la question du pourquoi l'appui sur la croix ferme l'interface mais ne quitte pas l'application. L'appui sur la croix génère deux évènements : "delete-event" et "destroy". Le premier signal te permet d'exécuter du code source sans pour autant fermer totalement l'application. Le deuxième va te permettre d'exécuter du code source avant l'arrêt de l'application. Dans ton cas ce dernier correspond à tes besoins. Pour quitter simplement la ligne suivante devrait suffire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    g_signal_connect (G_OBJECT (dialog), "destroy", GTK_SIGNAL_FUNC (gtk_main_quit), NULL);

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

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

    Informations forums :
    Inscription : Février 2008
    Messages : 2 291
    Points : 4 941
    Points
    4 941
    Billets dans le blog
    5
    Par défaut
    Puisque je vois aussi que tu t'essaies au Makefile je te propose de passer directement à Meson. Bien plus simple à utiliser.

    Pour revenir au code source à la première compilation on a deux warnings :
    main.c: In function ‘ButtonPress’:
    main.c:107:1: warning: no return statement in function returning non-void [-Wreturn-type]
    107 | }
    | ^
    main.c: In function ‘HandleExpose’:
    main.c:145:1: warning: no return statement in function returning non-void [-Wreturn-type]
    145 | }
    Les deux fonctions ButtonPress(); et HandleExpose(); retournent une valeur. Seulement il n'y a aucun return ! Il faut pour chacune d'entre-elles return FALSE;.

    Lorsqu'on lance l'application nous avons en console les warnings suivants :
    (test:10549): GLib-GObject-WARNING **: 17:00:43.810: ../../../gobject/gsignal.c:1325: unable to look up invalid signal name " expose_event " on type 'GtkDrawingArea'

    (test:10549): GLib-GObject-CRITICAL **: 17:00:43.810: g_signal_connect_closure_by_id: assertion 'signal_id > 0' failed

    (test:10549): GLib-GObject-WARNING **: 17:00:43.810: ../../../gobject/gsignal.c:1325: unable to look up invalid signal name "button_press _event" on type 'GtkDrawingArea'

    (test:10549): GLib-GObject-CRITICAL **: 17:00:43.810: g_signal_connect_closure_by_id: assertion 'signal_id > 0' failed
    Apparemment les signaux "expose_event" et "button_press_event" n'existent pas. Et pourtant si ! D'où vient le problème ? Il y a des espaces qui encadrent "expose_event" dans ton code source et il y a un espace entre le mot "press" et le tiret bas suivant. La syntaxe et la casse sont importantes .

    Voila ton code corrigé :
    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
    /* p 793-797 vdoc.pub_gtk-programming-in-c.pdf */
     
    # include <stdlib.h>
    # include <stdint.h> /* pour malloc */
     
    # include <gtk-2.0/gtk/gtk.h>
    # include <gtk-2.0/gdk/gdk.h>
     
    #define RED   1
    #define GREEN 2
    #define BLUE  4
     
    typedef struct piece {
      int x;
      int y;
      guint32 time;
      unsigned char color;
    } Piece;
     
    typedef struct cleardata {
      GtkWidget *w;
      GList **list;
    } ClearData;
     
    static GtkWidget *gRedPmap, *gGreenPmap, *gBluePmap;
    static unsigned char gColor = RED;
     
    static GtkWidget*
    NewPixmap( char *filename, GdkWindow *window, GdkColor *background )
    {
      GtkWidget *wpixmap;
      GdkPixmap *pixmap;
      GdkBitmap *mask;
     
      pixmap = gdk_pixmap_create_from_xpm( window, &mask, background, filename );
      wpixmap = gtk_pixmap_new( pixmap, mask );
     
      return wpixmap;
    }
     
    static void
    SetColor( GtkWidget *widget, gpointer arg )
    {
    //  gColor = (unsigned char) arg;
    // https://stackoverflow.com/questions/21323628/warning-cast-to-from-pointer-from-to-integer-of-different-size
      gColor = (intptr_t) arg;
    }
     
    static void
    ClearDrawing ( GtkWidget *widget, gpointer arg )
    {
      ClearData *p = (ClearData *) arg;
      GList **list = p->list;
      GList *tmp_list;
     
      for (tmp_list = *list; tmp_list; tmp_list = tmp_list->next)
          g_free(tmp_list->data);
     
      g_list_free(*list);
      *list = (GList *) NULL;
     
      gdk_window_clear( p->w->window );
    }
     
    static int
    CompFunc( gconstpointer a, gconstpointer b )
    {
      Piece *piece1, *piece2;
     
      piece1 = (Piece *) a;
      piece2 = (Piece *) b;
     
      if ( piece1->time < piece2->time )
        return FALSE;
      return TRUE;
    }
     
    static gint
    ButtonPress( GtkWidget *widget, GdkEventButton *event, gpointer arg )
    {
      ClearData *p = (ClearData *) arg;
      GList **items = (GList **) p->list;
      GtkPixmap *pixmap;
      Piece *piece;
     
      piece = (Piece *) malloc( sizeof( Piece ) );
      piece->color = gColor;
      piece->x = (gint) event->x;
      piece->y = (gint) event->y;
      piece->time = gdk_event_get_time( (GdkEvent *) event );
      *items = g_list_insert_sorted( *items, piece, CompFunc );
     
      switch ( piece->color ) {
        case RED:
          pixmap = GTK_PIXMAP( gRedPmap );
          break;
        case GREEN:
          pixmap = GTK_PIXMAP( gGreenPmap );
          break ;
        case BLUE:
          pixmap = GTK_PIXMAP( gBluePmap ) ;
          break ;
      }
     
      gdk_draw_pixmap( widget->window, widget->style->black_gc,
      pixmap->pixmap, 0, 0, piece->x, piece->y, -1, -1 );
     
      return FALSE;
    }
     
    static gint
    HandleExpose( GtkWidget *widget, GdkEventExpose *event, gpointer arg )
    {
      GList **p = (GList **) arg, *list = (GList *) *p;
      GdkRectangle rect, dest;
      GtkPixmap *pixmap;
      Piece *piece;
      int i;
     
      for ( i = 0; *p != (GList *) NULL; i++, *p = g_list_next( * p ) ) {
        piece = g_list_nth_data( (GList *) list, i );
        rect.x = piece->x;
        rect.y = piece->y;
        rect.width = rect.height = 20;
        if ( gdk_rectangle_intersect (
          &rect, &event->area, &dest ) == TRUE ) {
          switch ( piece->color ) {
            case RED:
              pixmap = GTK_PIXMAP( gRedPmap );
              break;
            case GREEN:
              pixmap = GTK_PIXMAP( gGreenPmap );
              break;
            case BLUE:
              pixmap = GTK_PIXMAP( gBluePmap );
              break;
            default:
              continue;
          }
          gdk_draw_pixmap( widget->window,
            widget->style->black_gc,
            pixmap->pixmap, 0, 0,
            piece->x, piece->y, -1, -1 );
        }
      }
      *p = list;
     
      return FALSE;
    }
     
    int main( int argc, char *argv[] )
    {
      GtkWidget *dialog, *button, *drawing, *toolbar;
      GList *items = (GList *) NULL;
      ClearData cd;
     
      gtk_init( &argc, &argv );
      dialog = gtk_dialog_new ();
      gtk_window_position( GTK_WINDOW( dialog ), GTK_WIN_POS_MOUSE );
      g_signal_connect (G_OBJECT (dialog), "destroy", GTK_SIGNAL_FUNC (gtk_main_quit), NULL);
      gtk_widget_show( dialog );
     
    //  toolbar = gtk_toolbar_new( GTK_ORIENTATION_HORIZONTAL, GTK_TOOLBAR_BOTH );
      toolbar = gtk_toolbar_new();
      gtk_toolbar_set_style(GTK_TOOLBAR(toolbar), GTK_TOOLBAR_BOTH);
     
      gRedPmap = NewPixmap( "red.xpm", dialog->window,
        &dialog->style->bg [GTK_STATE_NORMAL] ),
        gtk_toolbar_append_item( GTK_TOOLBAR(toolbar), "Red ",
        "Draw red square", NULL, gRedPmap,
        (GtkSignalFunc) SetColor, (gpointer) RED );
      gGreenPmap = NewPixmap ( "green.xpm", dialog->window,
        &dialog->style->bg[GTK_STATE_NORMAL] ),
        gtk_toolbar_append_item( GTK_TOOLBAR(toolbar), "Green",
        "Draw green square", NULL, gGreenPmap,
        (GtkSignalFunc) SetColor, (gpointer) GREEN );
      gBluePmap = NewPixmap( "blue.xpm", dialog->window,
        &dialog->style->bg [GTK_STATE_NORMAL] ),
        gtk_toolbar_append_item( GTK_TOOLBAR(toolbar), "Blue",
        "Draw blue square", NULL, gBluePmap,
        (GtkSignalFunc) SetColor, (gpointer) BLUE );
     
      gtk_box_pack_start( GTK_BOX( GTK_DIALOG( dialog )->vbox ), toolbar,
        FALSE, TRUE, 0 );
     
      drawing = gtk_drawing_area_new();
      gtk_drawing_area_size( GTK_DRAWING_AREA( drawing ), 320, 200 );
      gtk_signal_connect( GTK_OBJECT( drawing ), "expose_event" ,
        GTK_SIGNAL_FUNC( HandleExpose ), &items );
      gtk_widget_set_events( drawing,
        GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK);
      cd.w = drawing;
      cd.list = &items;
      gtk_signal_connect( GTK_OBJECT( drawing ), "button_press_event",
        GTK_SIGNAL_FUNC( ButtonPress ), &cd );
     
      gtk_box_pack_start( GTK_BOX( GTK_DIALOG( dialog )->vbox ), drawing,
        TRUE, TRUE, 0 );
     
      button = gtk_button_new_with_label( "Clear" );
      gtk_box_pack_start( GTK_BOX( GTK_DIALOG( dialog )->action_area ),
        button, TRUE, FALSE, 0 );
      gtk_signal_connect( GTK_OBJECT( button ), "clicked",
        GTK_SIGNAL_FUNC( ClearDrawing ), &cd );
     
      gtk_widget_show_all( dialog );
      gtk_main();
      return 0; // ajout moi
    }

  4. #4
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 726
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 726
    Points : 15 126
    Points
    15 126
    Par défaut
    Holà !

    (Désolé pour la réponse tardive, j'ai des milliards d'autres choses à faire...)

    Grand merci pour ton aide.

    En effet, des petites erreurs de typo suite à une extraction farfelue du texte pdf vers du txt se sont glissées ici et là et, si certaines étaient remontées par la compilation, d'autres sont passées à travers, mais ton œil de lynx les a repérées, ouf !

    J'ai corrigé et j'en suis là : toujours rien d'affiché, alors que les boutons réagissent aux clics, comme s'ils n'étaient pas connectés à leurs codes respectifs, et voilà ce qu'on devrait avoir, extrait du pdf :
    Nom : extrait-du-pdf.png
Affichages : 111
Taille : 84,2 Ko

    Une idée ?
    (cet aprème ch'suis pas là).
    Je rappelle qu'étant sous Linux, ça pourrait avoir une importance ? Je ne sais pas.

    Citation Envoyé par gerald3d Voir le message
    Puisque je vois aussi que tu t'essaies au Makefile je te propose de passer directement à Meson. Bien plus simple à utiliser.
    Pour le moment, je reste avec mon Makefile qui fonctionne, j'aimerais juste que ce bout de code fasse ce qu'il doit faire.
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

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

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

    Informations forums :
    Inscription : Février 2008
    Messages : 2 291
    Points : 4 941
    Points
    4 941
    Billets dans le blog
    5
    Par défaut
    Je suis aussi sous Linux. Nous parlons donc la même langue .

    Je n'avais pas tenté d'aller au bout des tests du code que je t'ai transmis. Ce code demande trois fichiers images au format xpm. Je les ai crée et te les transmets en pièces jointes dans un zip. Avec ces fichiers tout fonctionne parfaitement sans changer quoi que soit au code source.

    La preuve :

    Nom : gdk2_test_colors.png
Affichages : 134
Taille : 5,9 Ko
    Fichiers attachés Fichiers attachés

  6. #6
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 726
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 726
    Points : 15 126
    Points
    15 126
    Par défaut
    Citation Envoyé par gerald3d Voir le message
    Ce code demande trois fichiers images au format xpm. Je les ai créés et te les transmets en pièces jointes dans un zip. Avec ces fichiers tout fonctionne parfaitement sans changer quoi que soit au code source.
    Avec le même code source et tes fichiers (j'en avais créé trois ce matin), chez moi ça ne fonctionne pas :

    Nom : mon_test.png
Affichages : 105
Taille : 7,1 Ko

    Go figure...

    Une piste : j'avais déjà remarqué qu'avec Lazarus (FreePascal), il me fallait spécifier le chemin des fichiers d'images pour qu'un binaire stand-alone les trouve, alors que ce n'est pas nécessaire quand le binaire est exécuté dans l'environnement de l'edi, mais bon, j'ai testé en rajoutant les chemins et pas mieux,

    Maintenant, je veux bien essayer de comprendre pourquoi, mais il va falloir me prendre par la main...

    PS : d'où sortent ces mot "test" et rond avec la croix, si le code est celui d'hier ?
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

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

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

    Informations forums :
    Inscription : Février 2008
    Messages : 2 291
    Points : 4 941
    Points
    4 941
    Billets dans le blog
    5
    Par défaut
    Je vais répondre en commençant par la fin.

    Le mot "test" est le titre de la fenêtre. Ici l'application prend le nom du projet que j'ai créé pour essayer. Tu peux le changer en utilisant gtk_window_set_title();

    La croix dans le rond dépend du thème de bureau que tu utilises. Ça n'a rien à voir avec l'application proprement dite. Actuellement j'utilise le thème "Yaru". Si je le change par "Adwaita" j’obtiens ceci :

    Nom : Capture d’écran du 2022-03-02 11-07-49.png
Affichages : 91
Taille : 5,7 Ko

    Tu dis que ça ne fonctionne pas. Au vu de ta capture d'écran je suis déjà sûr que les fichiers images sont chargés puisque les boutons les affichent. Le logiciel te demande de choisir une couleur en cliquant sur un des boutons puis de cliquer n'importe où en dessous. Chaque clic va poser un carré de la couleur choisie. As-tu ce comportement ? Si non as-tu des warnings en console lors de la compilation ou de l'exécution ? Si oui peux-tu nous les montrer ?

  8. #8
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 726
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 726
    Points : 15 126
    Points
    15 126
    Par défaut
    Citation Envoyé par gerald3d Voir le message
    Je vais répondre en commençant par la fin.
    Ok, vu pour les détails cosmétiques.

    Citation Envoyé par gerald3d Voir le message
    l'application prend le nom du projet que j'ai créé
    Avec quel EDI ?

    Citation Envoyé par gerald3d Voir le message
    Le logiciel te demande de choisir une couleur en cliquant sur un des boutons puis de cliquer n'importe où en dessous. Chaque clic va poser un carré de la couleur choisie. As-tu ce comportement ?
    OMG !
    Mais rien ne me disait de cliquer dans la zone centrale !
    (d'où l'importance de l'ihm qui doit toujours nous prendre par la main.)

    Et comme le code gtk, pour moi, est tout sauf lisible et ne donne vraiment pas envie de le parcourir, je n'ai pas vu ce qui a dû te sauter aux yeux, si tu es habitué à ces/ses hiéroglyphes.

    Un grand merci à toi, oui, ça fonctionne as expected.
    Nom : yes.png
Affichages : 98
Taille : 7,9 Ko

    Et maintenant, le pourquoi je me suis lancé dans cette galère :
    Dans mon vieux Linux, la vieille version Gtk de l'explorateur de fichiers permet de passer le mode vue de icônes à petites images puis à liste (petites icônes) puis à liste détaillée d'une manière simplissime : il suffit de cliquer sur le menu "Voir" et on a tout sous les yeux, un clic pour choisir et hop !, c'est fait.
    Dans la nouvelle version toujours Gtk, c'est l'horreur : d'abord l'entrée "Voir" n'est pas au même endroit mais ensuite il faut chercher les entrées dans un sous-menu "mode de vue du répertoire" ou qqchse comme ça, qui oblige à glisser horizontalement la souris (l'enfer sur une longue distance) pour enfin atteindre le sous-menu qui me permettra de choisir le mode de vue dont l'ordre a en plus changé par rapport à la vieille version, bref, une galère à chaque utilisation.

    Mais quelqu'un ayant parlé de Qt je ne sais où récemment, j'ai voulu tester cet environnement et j'ai découvert que le même explorateur (pcmanfm) proposait, sous Qt, 4 boutons dans la barre d'outils pour accéder directement aux quatre options d'affichage donc ça, ce n'est que du bonheur.

    Et ça m'a fait germer l'idée de rajouter quatre boutons au code de l'explorateur sous Gtk, ce qui devrait ne pas être trop compliqué, depuis que tu m'as mis le pied à l'étrier, et je t'en remercie encore.

    Une dernière question : on voit dans l'image extraite du pdf (post # 4) que le bouton "Clear" en bas est centré sous une barre : la barre en question est-elle une barre ou le côté supérieur d'un panel aligné "en bas" ? Dans un cas comme dans l'autre, comment générer ça ?

    Et même question pour les trois boutons, qui ont chacun une bordure : une option du constructeur des boutons ?
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

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

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

    Informations forums :
    Inscription : Février 2008
    Messages : 2 291
    Points : 4 941
    Points
    4 941
    Billets dans le blog
    5
    Par défaut
    Quel IDE ?

    Je vais peut-être te faire peur mais j'utilise Emacs pour l'écriture du code source, la console pour créer un nouveau projet, que ce soit avec les Autotools ou Meson. Comme tu peux le voir j'ai tendance à avoir toujours les mains dans le moteur .
    Si tu désires un IDE orienté Gtk alors va jeter un œil à Anjuta.

    L'exemple présent est constitué ainsi :

    La fenêtre principale est un GtkDialog. Ça n'a aucun intérêt ici. L'auteur aurait tout aussi bien utiliser directement un GtkWindow. La particularité est qu'un GtkDialog dispose de deux GtkBox intégrés auxquels on accède directement. Voila un exemple court :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    GtkDialog *dialog = gtk_dialog_new ();
    GtkWidget *box = GTK_DIALOG( dialog )->vbox;
    GtkWidget *actionarea = GTK_DIALOG( dialog )->action_area;
    • box est un GtkBox qui est dans l'espace central de la fenêtre.
    • actionarea est un GtkBox dans lequel viennent se placer les boutons de gestion. Typiquement "Ouvrir", " Fermer", "Annuler", "Enregistrer"...


    Pour insérer un élément dans un GtkBox le code exemple utilise la fonction gtk_box_pack_start(GtkBox *box, GtkWidget *child, gboolean expand, gboolean fill, guint padding);.

    • expand demande au widget enfant de s'étendre le plus possible en fonction de l'espace disponible
    • fill rempli tout l'espace disponible
    • padding ajoute des espaces autour du widget enfant


    L'aspect de la barre en dessous et des boutons au dessus sont différents parce que Gtk2 a beaucoup évolué en terme de rendu depuis l'édition de ce livre. Si tu veux obtenir ce genre de rendu il faurdra ajouter un GtkSeparator par exemple dans box pour simuler l'ancien rendu.

    Pour résumer ne te formalises pas sur le rendu actuel. Dessine sur un papier comment tu veux ton interface. Ensuite tu pourras tenter d'avoir la même chose à l'écran.

    Nota bene : il existe Glade. Un logiciel WYSIWYG qui permet de construire une IHM à la souris. Tu peux l'utiliser pour comprendre comment agencer tes différents widgets. Mais je te déconseille fortement, surtout à tes débuts, de tenter de l'utiliser en lieu et place d'une construction en dure dans le code source. C'est le meilleur moyen pour ne jamais comprendre la philosophie Gtk+.

  10. #10
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 726
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 726
    Points : 15 126
    Points
    15 126
    Par défaut
    Hé bien il ne me reste plus qu'à te remercier encore une fois pour tous ces précieux conseils, j'ai suivi ton lien pour Anjuta, ça ressemble bien à ce que j'ai l'habitude de voir depuis 25 ans, ayant commencé avec VB4 sous Windows, puis Delphi 1, 3, 6, 7 et enfin Lazarus sous Linux.
    Et c'est vrai qu'un IDE bien agencé c'est quand même sympathique et ça fait gagner du temps mais, d'accord avec toi, faut aussi savoir lever le capot et dégainer l'éditeur de texte, des fois.

    Bon, je ne vais pas pouvoir mettre mon projet en chantier, il faut d'abord que je change de machine, ce qui va prendre du temps.

    Dommage que je puisse pas te plusser plusieurs fois,

    Allez hop !, et à bientôt pour de nouvelles aventures.
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

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

Discussions similaires

  1. Petite aide pour que mon appli soit utilisable via un VPN
    Par FredericB dans le forum C++Builder
    Réponses: 0
    Dernier message: 23/09/2007, 18h12
  2. Plusieurs Redemarrage PC client pour que la GPO soit appliquée
    Par vins5467 dans le forum Windows Serveur
    Réponses: 3
    Dernier message: 16/06/2007, 18h52
  3. Réponses: 5
    Dernier message: 08/12/2006, 18h26
  4. [Images] Décomposer un mot pour que chaque lettre soit un GIF
    Par Liondd dans le forum Bibliothèques et frameworks
    Réponses: 23
    Dernier message: 03/05/2006, 16h35
  5. CSS: comment faire pour que mes coins soit arrondi
    Par pierrot10 dans le forum Mise en page CSS
    Réponses: 6
    Dernier message: 16/02/2006, 12h08

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