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 :

Gtk_led modernisé customisation Gtk


Sujet :

GTK+ avec C & C++

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    147
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 147
    Points : 88
    Points
    88
    Par défaut Gtk_led modernisé customisation Gtk
    hello la team Gtk

    J'essaie de me familiariser avec la customisation des widgets.

    J'ai travaillé un code avec diverses avancées liées aux évolutions de Glib, Gtk etc....
    Et j'ai lu pas mal de doc

    il me reste à résoudre probablement un dernier point au lancement je ne vois pas le dessin de la led mais si je clique sur le bouton elle apparait


    voici les 3 codes en chantier et le meson.build correspondant

    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
    /* gtkled.h */
     
    #ifndef __GTK_LED_H
    #define __GTK_LED_H
     
    #include <gtk/gtk.h>
    #include <cairo.h>
     
    G_BEGIN_DECLS
     
    #define CB_TEST
     
     
    G_DECLARE_FINAL_TYPE(GtkLed, gtk_led,GTK , LED , GtkWidget)
    /** signification des paramètres
     * le préfixe GtkLed pour la classe GtkLedClass
     * gtk_led pour définir le type gtk_led_get_type()
     * le transtypage GTK_LED
     * l'ancêtre GtkWidget
     **/
     
     /* Type definition */
    typedef struct _GtkLedPrivate GtkLedPrivate;
     
    struct _GtkLed 
    {
    	GtkWidget parent;
     
    	/*< Private >*/
    	GtkLedPrivate *priv;
    };
     
    struct _GtkLedClass 
    {
       GtkWidgetClass parent_class;
    };
     
    /* Public API */
    gboolean gtk_led_get_state (GtkLed * led);
    void gtk_led_set_state (GtkLed * led, gboolean state);
    GtkWidget * gtk_led_new (const gchar * on_image,
                             const gchar * off_image,
                             gboolean state);
     
    G_END_DECLS
     
    #endif /* __GTK_LED_H */
    puis

    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
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
    392
    393
    394
    395
    396
    397
    398
    399
    400
    401
    402
    403
    404
    405
    #include "gtkled.h"
     
    /* gtkled.c */
     
    /* Private data structure */
    struct _GtkLedPrivate 
    {    
    	const gchar * on_image;
    	const gchar * off_image;
     
    	GdkPixbuf * on_pixbuf;
    	GdkPixbuf * off_pixbuf;
     
    	gint width;
    	gint height;
     
    	gboolean state;
    	GdkWindow *window;
    };
    enum {
      PROP_0,
      PROP_IMAGE_ON,
      PROP_IMAGE_OFF,
      PROP_STATE
    };
     
    /* Internal API */
    static void gtk_led_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
    static void gtk_led_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
    static void gtk_led_class_init (GtkLedClass * klass);
    static void gtk_led_init (GtkLed * led);
    static void gtk_led_load_image (GtkLed * led);
    static void gtk_led_size_request (GtkWidget * widget, GtkRequisition * requisition);
    static void gtk_led_get_preferred_height (GtkWidget *widget, gint *minimal_height, gint *natural_height);
    static void gtk_led_get_preferred_width (GtkWidget *widget, gint *minimal_width, gint *natural_width);
    static void gtk_led_size_allocate (GtkWidget * widget, GtkAllocation * allocation);
    static void gtk_led_realize (GtkWidget * widget);
    static void gtk_led_paint (GtkWidget * widget);
    static void gtk_led_finalize (GObject * object);
     
    /* Define variable GTK_TYPE_LED in order to represent GType fonction */
    #define GTK_TYPE_LED gtk_led_get_type()
    /* Define type */
    G_DEFINE_TYPE(GtkLed, gtk_led, GTK_TYPE_WIDGET)
    /** signification des paramètres pour G_DEFINE_TYPE(GtkLed, gtk_led, GTK_TYPE_WIDGET)
     * le même préfixe GtkLed que pour la classe GtkLedClass
     * implementation de la fonction gtk_led_get_type avec un  protocole standard
     * define a parent class pointer accessible from the whole .c file
     **/
     
    /* Initialization */
    static void gtk_led_class_init (GtkLedClass * klass)
    {
    	GtkWidgetClass * widget_class;
    	GObjectClass * object_class;
    	GParamSpec *pspec;
    	#ifdef CB_TEST
    		g_print ("gtk_led_class_init\n");
    	#endif
    	widget_class = (GtkWidgetClass *) klass;
    	object_class = (GObjectClass *) klass;
     
    	/* Override widget class methods */
    	object_class->set_property = gtk_led_set_property;
    	object_class->get_property = gtk_led_get_property;
     
    	widget_class->realize = gtk_led_realize;
    	widget_class->get_preferred_width = gtk_led_get_preferred_width;
    	widget_class->get_preferred_height = gtk_led_get_preferred_height;
     
    	widget_class->size_allocate = gtk_led_size_allocate;
     
    	object_class->finalize = gtk_led_finalize;
    	/************************/
    	pspec = g_param_spec_boolean ("state",
                                    "State",
                                    "True when the led is switched_on",
                                    FALSE,
                                    G_PARAM_READWRITE);           
    	g_object_class_install_property (object_class, PROP_STATE, pspec);
    	/************************/
    	pspec = g_param_spec_string ("on-image",
                                   "On-Image",
                                   "Path for the led on image file",
                                   "",
                                   G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
    	g_object_class_install_property (object_class, PROP_IMAGE_ON, pspec);
    	/************************/
    	pspec = g_param_spec_string ("off-image",
                                   "Off-Image",
                                   "Path for the led off image file",
                                   "",
                                   G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
    	g_object_class_install_property (object_class, PROP_IMAGE_OFF, pspec);
     
    	g_type_class_add_private (klass, sizeof(GtkLedPrivate));
     
    	g_print ("\n gtk_led_class_init ligne SUCCESS %d\n", __LINE__);
    }
     
    static void gtk_led_init (GtkLed * led)
    {
    	#ifdef CB_TEST
    		g_print ("gtk_led_init\n");
    	#endif
    	GtkLedPrivate *priv = G_TYPE_INSTANCE_GET_PRIVATE(led, GTK_TYPE_LED, GtkLedPrivate);
     
    	gtk_widget_set_has_window(GTK_WIDGET(led), TRUE);
    	priv->on_image = NULL;
    	priv->off_image = NULL;
    	priv->on_pixbuf = NULL;
    	priv->off_pixbuf = NULL;
    	priv->width = 0;
    	priv->height =0;
    	priv->state = FALSE;
    	g_print ("dans gtk_led_init les tailles sont %d et %d \n",priv->width,priv->height);
     
    	/* Create cache for faster access */
    	led->priv = priv;
    	g_print ("\n gtk_led_init ligne SUCCESS %d\n", __LINE__);
    }
     
    static void gtk_led_set_property (GObject           *object,
                          guint             prop_id,
                          const GValue      *value,
                          GParamSpec        *pspec)
    {
    	#ifdef CB_TEST
    		g_print ("gtk_led_set_property\n");
    	#endif
    	GtkLed * led = GTK_LED (object);;
    	switch (prop_id) {
    		case PROP_STATE:
    		  gtk_led_set_state (led, g_value_get_boolean(value));
    		  break;
    		case PROP_IMAGE_ON:
    		  g_free (led->priv->on_image);
    		  led->priv->on_image = g_value_dup_string (value);
    		  break;
     
    		case PROP_IMAGE_OFF:
    		  g_free (led->priv->off_image);
    		  led->priv->off_image = g_value_dup_string (value);
    		  break;
    		default:
    		  G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
    	}
    }
     
    static void gtk_led_get_property (GObject           *object,
                          guint             prop_id,
                          GValue            *value,
                          GParamSpec        *pspec)
    {
    	#ifdef CB_TEST
    		g_print ("gtk_led_get_property\n");
    	#endif
    	GtkLed * led = GTK_LED (object);
    	switch (prop_id) {
    		case PROP_STATE:
    		  g_value_set_boolean (value, led->priv->state);
    		  break;
     
    		case PROP_IMAGE_ON:
    		  g_value_set_string (value, led->priv->on_image);
    		  break;
     
    		case PROP_IMAGE_OFF:
    		  g_value_set_string (value, led->priv->off_image);
    		  break;
     
    		default:
    		  G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      }
    }
    gboolean gtk_led_get_state (GtkLed * led)
    {
    	g_return_val_if_fail(GTK_LED(led), 0);
    	#ifdef CB_TEST
    		g_print ("gtk_led_get_state\n");
    	#endif
    	g_print ("gtk_led_get_state Etat=%d (1 = ON 0=OFF)\n",led->priv->state);
    	g_print ("\n gtk_led_get_state ligne ok %d\n", __LINE__);
    	return (led->priv->state);
    }
     
    void gtk_led_set_state (GtkLed * led, gboolean state)
    {
    	#ifdef CB_TEST
    		g_print ("gtk_led_set_state\n");
    	#endif
       led->priv->state = state;
       gtk_led_paint (GTK_WIDGET (led));
       g_print ("\n gtk_led_set_state ligne ok %d\n", __LINE__);
    }
     
    GtkWidget * gtk_led_new (const gchar * on_image,
    						 const gchar * off_image,
    						 gboolean state)
    {
    	GtkLed * led = NULL;
    	#ifdef CB_TEST
    		g_print ("gtk_led_new\n");
    	#endif
    	if (on_image != NULL && off_image != NULL) 
    	{
    		// la taille de la zone led n'est pas allouée donc il manque quelque chose
    		led = g_object_new (GTK_TYPE_LED,
                           "state", state,
                           "on-image", on_image,
                           "off-image", off_image,
                           NULL);
    		gtk_led_load_image (led);
    		g_print ("\n gtk_led_new ligne SUCCESS %d\n", __LINE__);
    		return GTK_WIDGET (led);
    	}
    	g_print ("\n gtk_led_new ligne FATAL ERROR %d\n", __LINE__);
    	return GTK_WIDGET (led);
    }
     
    static void gtk_led_get_preferred_width (GtkWidget *widget, gint *minimal_width, gint *natural_width)
    {
    	/** la fonction établit une largeur   compatible avec le fichier image   **/
    	g_return_if_fail (widget != NULL);
    	g_return_if_fail (GTK_LED (widget));
    	#ifdef CB_TEST
    		g_print ("gtk_led_get_preferred_width\n");
    	#endif
    	GtkRequisition requisition;
     
    	gtk_led_size_request (widget, &requisition);
    	*minimal_width = *natural_width = requisition.width;
    	g_print ("dans gtk_led_get_preferred_width les tailles sont %d  \n",requisition.width);
    	g_print ("\n gtk_led_get_preferred_width ligne ok %d\n", __LINE__);
    }
     
    static void gtk_led_get_preferred_height (GtkWidget *widget, gint *minimal_height, gint *natural_height)
    {
    	/** la fonction établit une hauteur  compatible avec le fichier image**/
    	g_return_if_fail (widget != NULL);
    	g_return_if_fail (GTK_LED (widget));
    	#ifdef CB_TEST
    		g_print ("gtk_led_get_preferred_height\n");
    	#endif
    	GtkRequisition requisition;
     
    	gtk_led_size_request (widget, &requisition);
    	*minimal_height = *natural_height = requisition.height;
    	g_print ("dans gtk_led_get_preferred_height les tailles sont %d  \n",requisition.height);
    	g_print ("\n gtk_led_get_preferred_height ligne ok %d\n", __LINE__);
    }
     
    static void gtk_led_size_request (GtkWidget * widget, GtkRequisition * requisition)
    {
    	/** nous stockons la taille préférée de notre widget, cette fonction ne sert qu'a cela
             * mais requisition sera par la suite consulté **/
    	g_return_if_fail (widget != NULL);
    	g_return_if_fail (GTK_LED (widget));
    	#ifdef CB_TEST
    		g_print ("gtk_led_size_request\n");
    	#endif	
     
    	GtkLedPrivate *priv = GTK_LED(widget)->priv;
    	requisition->width = priv->width;
    	requisition->height = priv->height;
    	g_print ("dans gtk_led_size_request les tailles sont %d et %d \n",priv->width,priv->height);
    	g_print ("\n gtk_led_size_request ligne ok %d\n", __LINE__);
    }
     
    void gtk_led_load_image (GtkLed * led)
    {
    	#ifdef CB_TEST
    		g_print ("gtk_led_load_image\n");
    	#endif
    	GtkLedPrivate *priv = led->priv;
    	priv->on_pixbuf = gdk_pixbuf_new_from_file (priv->on_image, NULL);
    	priv->off_pixbuf = gdk_pixbuf_new_from_file (priv->off_image, NULL);
    	/** c'est ici que ces paramètres son initialisé avec la taille des pixbuf **/
    	priv->width = gdk_pixbuf_get_width (priv->on_pixbuf);
    	priv->height = gdk_pixbuf_get_height (priv->on_pixbuf);
    	g_print ("dans gtk_led_load_image les tailles sont %d et %d \n",priv->width,priv->height);
    	g_print ("\n gtk_led_load_image ligne ok %d\n", __LINE__);
    }
     
    static void gtk_led_size_allocate (GtkWidget * widget, GtkAllocation * allocation)
    {
    	/** Cette fonction sera appelée par le conteneur dans lequel se trouvera notre widget,
             * une fois que les contraintes qui sont imposées au conteneur sont fixées, 
             * ça permet au conteneur de redimensionner au mieux notre widget gtkled,
             * d'après le résultat obtenu dans le second argument de la fonction avec
             * gtk_widget_set_allocation(widget, allocation);
             * puis nous lançons la demande de déplacement, et re-dimensionnement, 
             * avec l'appel à gdk_window_move_resize.
             * C'est un protocole qu'on retrouve dans les divers exemples  **/ 
    	g_return_if_fail (widget != NULL);
    	g_return_if_fail (GTK_LED (widget));
    	#ifdef CB_TEST
    		g_print ("gtk_led_size_allocate\n");
    	#endif
    	GtkLedPrivate *priv = GTK_LED(widget)->priv;
     
    	gtk_widget_set_allocation(widget, allocation);
     
    	if (gtk_widget_get_realized(widget)) 
    	{
    		g_print ("\n gtk_led_size_allocate ligne GOOOOOOOOOOOOOD %d\n", __LINE__);
    		g_print ("dans gtk_led_size_allocate les tailles private sont %d et %d \n",priv->width,priv->height);
    		g_print ("dans gtk_led_size_allocate les tailles allocation sont %d et %d \n",allocation->width,allocation->height);
    		gdk_window_move_resize (priv->window, 
    								allocation->x, 
    								allocation->y, 
    								priv->width, priv->height);
    	}
    	else
    		g_print ("\n gtk_led_size_allocate ligne BAAAAAAD  %d\n", __LINE__);
    	g_print ("\n gtk_led_size_allocate ligne ok %d\n", __LINE__);
    }
     
    static void gtk_led_realize (GtkWidget * widget)
    {
    	/** cette fonction est au coeur du dispositif c'est ici que la fenêtre est créé
             * avec les bonnes dimensions
             **/
    	g_return_if_fail (widget != NULL);
    	g_return_if_fail (GTK_LED (widget));
    	#ifdef CB_TEST
    		g_print ("gtk_led_realize\n");
    	#endif
    	GtkLedPrivate *priv = GTK_LED(widget)->priv;
    	GdkWindowAttr attributes;
    	guint attributes_mask;
    	GtkAllocation allocation;
     
    	gtk_widget_set_realized(widget, TRUE);
     
    	gtk_widget_get_allocation(widget, &allocation);
     
    	attributes.window_type = GDK_WINDOW_CHILD;
    	attributes.x = allocation.x;
    	attributes.y = allocation.y;
    	attributes.width = allocation.width;
    	attributes.height = allocation.height;
    	attributes.wclass = GDK_INPUT_OUTPUT;
    	attributes.event_mask = gtk_widget_get_events (widget) | GDK_EXPOSURE_MASK;
     
    	attributes_mask = GDK_WA_X | GDK_WA_Y;
     
    	priv->window = gdk_window_new (
    	  gtk_widget_get_parent_window (widget),
    	  & attributes, attributes_mask);
     
    	gdk_window_set_user_data (priv->window, widget);
    	gtk_widget_set_window(widget, priv->window);
     
    	g_print ("\n gtk_led_realize ligne ok %d\n", __LINE__);
    }
     
    static void gtk_led_paint (GtkWidget * widget)
    {
    	g_return_if_fail (widget != NULL);
    	g_return_if_fail (GTK_LED (widget));
    	GdkPixbuf * pixbuf = NULL;
    	gint center_x = 0;
    	gint center_y = 0;
     
    	GtkAllocation allocation;
    	gtk_widget_get_allocation(widget, &allocation);
    	GtkLedPrivate *priv = GTK_LED(widget)->priv;
     
    	if (gtk_widget_get_realized (widget)) 
    	{
    		center_x = (allocation.width / 2) - (priv->width / 2);
    		center_y = (allocation.height / 2) - (priv->height / 2);
     
    		if (priv->state)
    			pixbuf = priv->on_pixbuf;
    		else
    			pixbuf = priv->off_pixbuf;
    		cairo_t *cr = gdk_cairo_create (priv->window);
    		gdk_cairo_set_source_pixbuf (cr, pixbuf, center_x, center_y);
    		cairo_paint (cr);
    		cairo_destroy (cr);
    	}
    }
     
    static void gtk_led_finalize (GObject * object)
    {
    	// Destruction des données privées si nécessaire
    	GtkLed * led;
    	GtkLedPrivate *priv;
    	#ifdef CB_TEST
    		g_print ("gtk_led_finalize\n");
    	#endif
    	led = GTK_LED (object);
    	priv = G_TYPE_INSTANCE_GET_PRIVATE(led, GTK_TYPE_LED, GtkLedPrivate);
     
    	if (priv->on_pixbuf != NULL && priv->off_pixbuf != NULL) 
    	{
    		g_object_unref (priv->on_pixbuf);
    		g_object_unref (priv->off_pixbuf);
    		priv->on_pixbuf = NULL;
    		priv->off_pixbuf = NULL;
    	}
    	g_print ("\n gtk_led_finalize ligne ok %d\n", __LINE__);
    }
    pour finir le code test
    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
    #include <stdio.h>
    //#include <stdlib.h>
    #include <gtk/gtk.h>
     
    #include "gtkled.h"
     
    static void cb_switch (GtkWidget * widget, gpointer data)
    {
    	#ifdef CB_TEST
    		g_print ("cb_switch\n");
    	#endif
       GtkWidget * led = (GtkWidget *) data;
       gtk_led_set_state (GTK_LED (led), ! gtk_led_get_state (GTK_LED (led)));
       g_print ("\n cb_switch ligne SUCCESS %d\n", __LINE__);
    }
     
    int main (int argc, char ** argv)
    {
    	GtkWidget * window;
    	GtkWidget * hbox;
    	GtkWidget * button;
    	GtkWidget * led = NULL;
     
    	gtk_init (& argc, & argv);
    	/*
    	* Creation de la fenetre principale et ajout d'un container.
    	*/
    	window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    	gtk_window_set_title (GTK_WINDOW (window), "Test de GtkLed");
    	gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_CENTER);
    	gtk_window_set_default_size (GTK_WINDOW (window), 250, 50);
     
    	g_signal_connect (window,"destroy",G_CALLBACK (gtk_main_quit),NULL);
     
    	hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
     
    	gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
    	gtk_container_add (GTK_CONTAINER (window), hbox);
    	/*
    	* Creation d'un bouton et d'un GtkLed.
    	*/
    	button = gtk_button_new_with_label ("Switch led state");
    	gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
     
    	led = gtk_led_new ("led_on.png", "led_off.png", TRUE);
     
    	if (led !=NULL) 
    	{
    		gtk_box_pack_start (GTK_BOX (hbox), led, TRUE, TRUE, 0);
    		g_signal_connect (button, "clicked",G_CALLBACK (cb_switch),(gpointer) led);
    	} 
    	else
    		printf ("Impossible de créer le widget GtkLed !\n");
    	gtk_widget_show_all (window);
    	gtk_main ();
    	return EXIT_SUCCESS;
    }
    le meson.build

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    project('gtkled', 'c')
    gtkdep = dependency('gtk+-3.0')
    scr= [ 'gtkled.h','main.c','gtkled.c']
    executable('gtkled', scr, dependencies : gtkdep)
    Je me suis inspiré de ce tuto
    https://franckh.developpez.com/tutor...eation-widget/


    Comme indiqué plus haut je ne comprend pas pourquoi la led n'est pas affichée au lancement du programme test et affiché ensuite si on clique sur le bouton.

    Si un expert GTK peut m'expliquer ce qui manque je l'en remercie d'avance.

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

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

    Informations forums :
    Inscription : Février 2008
    Messages : 2 296
    Points : 4 949
    Points
    4 949
    Billets dans le blog
    5
    Par défaut
    Bonjour @turboiii.

    Je vois que tu t'essayes à la programmation orientée objet façon Gtk. Bravo. C'est la dernière étape pour faire le tour de cette bibliothèque.

    Tu t'es inspiré du tuto de Franck.H comme je l'ai fait en mon temps. Il commence à "vieillir un peu" mais ca reste une bonne base pour appréhender les principes.

    Avant tout je précise que j'utilise la v3.24.13-1 de Gtk+.

    J'ai pris ton code et lancé une première compilation. Voila le résultat :
    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
    gtkled.c: In function ‘gtk_led_class_init’:
    gtkled.c:96:2: warning: ‘g_type_class_add_private’ is deprecated [-Wdeprecated-declarations]
       96 |  g_type_class_add_private (klass, sizeof(GtkLedPrivate));
          |  ^~~~~~~~~~~~~~~~~~~~~~~~
    In file included from /usr/include/glib-2.0/gobject/gobject.h:24,
                     from /usr/include/glib-2.0/gobject/gbinding.h:29,
                     from /usr/include/glib-2.0/glib-object.h:23,
                     from /usr/include/glib-2.0/gio/gioenums.h:28,
                     from /usr/include/glib-2.0/gio/giotypes.h:28,
                     from /usr/include/glib-2.0/gio/gio.h:26,
                     from /usr/include/gtk-3.0/gdk/gdkapplaunchcontext.h:28,
                     from /usr/include/gtk-3.0/gdk/gdk.h:32,
                     from /usr/include/gtk-3.0/gtk/gtk.h:30,
                     from gtkled.h:6,
                     from gtkled.c:1:
    /usr/include/glib-2.0/gobject/gtype.h:1308:10: note: declared here
     1308 | void     g_type_class_add_private       (gpointer                    g_class,
          |          ^~~~~~~~~~~~~~~~~~~~~~~~
    gtkled.c: In function ‘gtk_led_init’:
    gtkled.c:106:13: warning: G_ADD_PRIVATE
      106 |  GtkLedPrivate *priv = G_TYPE_INSTANCE_GET_PRIVATE(led, GTK_TYPE_LED, GtkLedPrivate);
          |             ^~~~~~~~~~~~~~~
    gtkled.c: In function ‘gtk_led_set_property’:
    gtkled.c:137:22: warning: passing argument 1 of ‘g_free’ discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]
      137 |     g_free (led->priv->on_image);
          |             ~~~~~~~~~^~~~~~~~~~
    In file included from /usr/include/glib-2.0/glib/glist.h:32,
                     from /usr/include/glib-2.0/glib/ghash.h:33,
                     from /usr/include/glib-2.0/glib.h:50,
                     from /usr/include/gtk-3.0/gdk/gdkconfig.h:13,
                     from /usr/include/gtk-3.0/gdk/gdk.h:30,
                     from /usr/include/gtk-3.0/gtk/gtk.h:30,
                     from gtkled.h:6,
                     from gtkled.c:1:
    /usr/include/glib-2.0/glib/gmem.h:71:35: note: expected ‘gpointer’ {aka ‘void *’} but argument is of type ‘const gchar *’ {aka ‘const char *’}
       71 | void  g_free           (gpointer  mem);
          |                         ~~~~~~~~~~^~~
    gtkled.c:142:22: warning: passing argument 1 of ‘g_free’ discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]
      142 |     g_free (led->priv->off_image);
          |             ~~~~~~~~~^~~~~~~~~~~
    In file included from /usr/include/glib-2.0/glib/glist.h:32,
                     from /usr/include/glib-2.0/glib/ghash.h:33,
                     from /usr/include/glib-2.0/glib.h:50,
                     from /usr/include/gtk-3.0/gdk/gdkconfig.h:13,
                     from /usr/include/gtk-3.0/gdk/gdk.h:30,
                     from /usr/include/gtk-3.0/gtk/gtk.h:30,
                     from gtkled.h:6,
                     from gtkled.c:1:
    /usr/include/glib-2.0/glib/gmem.h:71:35: note: expected ‘gpointer’ {aka ‘void *’} but argument is of type ‘const gchar *’ {aka ‘const char *’}
       71 | void  g_free           (gpointer  mem);
          |                         ~~~~~~~~~~^~~
    gtkled.c: In function ‘gtk_led_paint’:
    gtkled.c:379:3: warning: ‘gdk_cairo_create’ is deprecated: Use 'gdk_window_begin_draw_frame() and gdk_drawing_context_get_cairo_context()' instead [-Wdeprecated-declarations]
      379 |   cairo_t *cr = gdk_cairo_create (priv->window);
          |   ^~~~~~~
    In file included from /usr/include/gtk-3.0/gdk/gdk.h:33,
                     from /usr/include/gtk-3.0/gtk/gtk.h:30,
                     from gtkled.h:6,
                     from gtkled.c:1:
    /usr/include/gtk-3.0/gdk/gdkcairo.h:35:12: note: declared here
       35 | cairo_t  * gdk_cairo_create             (GdkWindow          *window);
          |            ^~~~~~~~~~~~~~~~
    gtkled.c: In function ‘gtk_led_finalize’:
    gtkled.c:395:13: warning: G_ADD_PRIVATE
      395 |  priv = G_TYPE_INSTANCE_GET_PRIVATE(led, GTK_TYPE_LED, GtkLedPrivate);
          |             ^~~~~~~~~~~~~~~
    Comme tu peux le voir il y a quelques problèmes . Mais ca ne l'empêche pas de fonctionner.

    Si nous faisons abstraction des warnings de compilation ton problème vient de l'appel à gtk_led_paint (). Comme le widget n'est pas encore construit et affiché, la fonction gtk_led_paint (); ne fait rien.

    Lorsqu'on construit un nouveau widget l'idéal est d'utiliser les fonctions virtuelles mises à notre disposition. Pour les connaitre il suffit de consulter la documentation officielle au rayon GtkWidgetClass.
    Parmis toute la liste disponible il y a celle-ci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    gboolean (* draw)	       (GtkWidget	 *widget,
                                    cairo_t          *cr);
    Nous allons l'utiliser pour y connecter notre propre fonction d'affichage. Pour se faire il faut déjà que notre fonction est le même prototype. Donc la fonction static void gtk_led_paint (GtkWidget * widget); va devenir static gboolean gtk_led_paint (GtkWidget * widget, cairo_t *cr);. On voit déjà le premier avantage que l'on va gagner. Nous allons avoir à notre disposition le contexte graphique du widget concerné. Plus besoin d'en créer un .
    Il nous faut ensuite indiquer à notre widget cette fameuse fonction. Cela se fait dans la fonction static void gtk_led_class_init (GtkLedClass * klass); :
    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
    static void gtk_led_class_init (GtkLedClass * klass)
    {
    	GtkWidgetClass * widget_class;
    	GObjectClass * object_class;
    	GParamSpec *pspec;
    	#ifdef CB_TEST
    		g_print ("gtk_led_class_init\n");
    	#endif
    	widget_class = (GtkWidgetClass *) klass;
    	object_class = (GObjectClass *) klass;
     
    	/* Override widget class methods */
    	object_class->set_property = gtk_led_set_property;
    	object_class->get_property = gtk_led_get_property;
     
    	widget_class->realize = gtk_led_realize;
    	widget_class->get_preferred_width = gtk_led_get_preferred_width;
    	widget_class->get_preferred_height = gtk_led_get_preferred_height;
    
    	widget_class->draw = gtk_led_paint;
            ...
    Modifiions maintenant la fonction gtk_led_paint (); :. J'en profite pour modifier aussi la manière dont tu testes les paramètres transmis :
    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
    static gboolean gtk_led_paint (GtkWidget *widget, cairo_t *cr)
    {
      g_return_val_if_fail (GTK_IS_LED (widget), FALSE);
      GdkPixbuf * pixbuf = NULL;
      gint center_x = 0;
      gint center_y = 0;
     
      GtkAllocation allocation;
      gtk_widget_get_allocation(widget, &allocation);
      GtkLedPrivate *priv = GTK_LED(widget)->priv;
     
      center_x = (allocation.width / 2) - (priv->width / 2);
      center_y = (allocation.height / 2) - (priv->height / 2);
     
      if (priv->state)
        pixbuf = priv->on_pixbuf;
      else
        pixbuf = priv->off_pixbuf;
      /* cairo_t *cr = gdk_cairo_create (priv->window); */
      gdk_cairo_set_source_pixbuf (cr, pixbuf, center_x, center_y);
      cairo_paint (cr);
      /* cairo_destroy (cr); */
     
      return FALSE;
    }
    Comme tu peux le remarquer, plus besoin non plus de tester si le widget est construit. Si la fonction est appelée, c'est qu'il est construit.

    Il ne nous reste plus qu'à modifier la fonction gtk_led_set_state (); pouisqu'elle fait appel à gtk_led_paint ();. Plutôt que de l'appeler directement j'utilise la fonction générique livrée par les GtkWidget. Ca permet de récupérer correctement le contexte graphique :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    void gtk_led_set_state (GtkLed * led, gboolean state)
    {
      g_return_if_fail (GTK_IS_LED (led));
      
    #ifdef CB_TEST
      g_print ("gtk_led_set_state\n");
    #endif
      led->priv->state = state;
      /* gtk_led_paint (GTK_WIDGET (led)); */
      gtk_widget_queue_draw (GTK_WIDGET (led));
      g_print ("\n gtk_led_set_state ligne ok %d\n", __LINE__);
    }
    Pense enfin à modifier la déclaration du prototype de la fonction gtk_led_paint (); :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    static gboolean gtk_led_paint (GtkWidget *widget, cairo_t *cr);

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    147
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 147
    Points : 88
    Points
    88
    Par défaut
    Bonsoir gérald

    je comprends que finalement il y est quelques différences avec tes résultats puisque ma version de Gtk est la 3.22.30 sur Ubuntu 18 LTS. De mon côté je n'ai pas tous ces warning évidemment.....
    Je vais étudier en détail tes réponses qui sont très détaillées.
    Merci encore de ton aide précieuse.

Discussions similaires

  1. Compilation GTK+ DevC++
    Par GLDavid dans le forum GTK+ avec C & C++
    Réponses: 2
    Dernier message: 30/06/2004, 23h04
  2. [web] Installation de gtk
    Par toto_titi dans le forum Interfaces Graphiques
    Réponses: 3
    Dernier message: 30/06/2003, 11h24
  3. [GTK]instal devPack avec dev c++
    Par FreshVic dans le forum Autres éditeurs
    Réponses: 8
    Dernier message: 15/04/2003, 16h48
  4. [Kylix] Kylix GTK et QT
    Par mailstef dans le forum EDI
    Réponses: 2
    Dernier message: 19/11/2002, 21h53
  5. [GTK]PB Librairie GTK+ sous dev-c++
    Par wozzy dans le forum Dev-C++
    Réponses: 15
    Dernier message: 05/11/2002, 14h55

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